{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Chapter 3 – Classification**\n",
    "\n",
    "_This notebook contains all the sample code and solutions to the exercises in chapter 3._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/ageron/handson-ml2/blob/master/03_classification.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Setup"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, let's import a few common modules, ensure MatplotLib plots figures inline and prepare a function to save the figures. We also check that Python 3.5 or later is installed (although Python 2.x may work, it is deprecated so we strongly recommend you use Python 3 instead), as well as Scikit-Learn ≥0.20."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Python ≥3.5 is required\n",
    "import sys\n",
    "assert sys.version_info >= (3, 5)\n",
    "\n",
    "# Scikit-Learn ≥0.20 is required\n",
    "import sklearn\n",
    "assert sklearn.__version__ >= \"0.20\"\n",
    "\n",
    "# Common imports\n",
    "import numpy as np\n",
    "import os\n",
    "\n",
    "# to make this notebook's output stable across runs\n",
    "np.random.seed(42)\n",
    "\n",
    "# To plot pretty figures\n",
    "%matplotlib inline\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "mpl.rc('axes', labelsize=14)\n",
    "mpl.rc('xtick', labelsize=12)\n",
    "mpl.rc('ytick', labelsize=12)\n",
    "\n",
    "# Where to save the figures\n",
    "PROJECT_ROOT_DIR = \".\"\n",
    "CHAPTER_ID = \"classification\"\n",
    "IMAGES_PATH = os.path.join(PROJECT_ROOT_DIR, \"images\", CHAPTER_ID)\n",
    "os.makedirs(IMAGES_PATH, exist_ok=True)\n",
    "\n",
    "def save_fig(fig_id, tight_layout=True, fig_extension=\"png\", resolution=300):\n",
    "    path = os.path.join(IMAGES_PATH, fig_id + \".\" + fig_extension)\n",
    "    print(\"Saving figure\", fig_id)\n",
    "    if tight_layout:\n",
    "        plt.tight_layout()\n",
    "    plt.savefig(path, format=fig_extension, dpi=resolution)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MNIST"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['data', 'target', 'feature_names', 'DESCR', 'details', 'categories', 'url'])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_openml\n",
    "mnist = fetch_openml('mnist_784', version=1)\n",
    "mnist.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000, 784)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X, y = mnist[\"data\"], mnist[\"target\"]\n",
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000,)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "784"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "28 * 28"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure some_digit_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "some_digit = X[0]\n",
    "some_digit_image = some_digit.reshape(28, 28)\n",
    "plt.imshow(some_digit_image, cmap=mpl.cm.binary)\n",
    "plt.axis(\"off\")\n",
    "\n",
    "save_fig(\"some_digit_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'5'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = y.astype(np.uint8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_digit(data):\n",
    "    image = data.reshape(28, 28)\n",
    "    plt.imshow(image, cmap = mpl.cm.binary,\n",
    "               interpolation=\"nearest\")\n",
    "    plt.axis(\"off\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EXTRA\n",
    "def plot_digits(instances, images_per_row=10, **options):\n",
    "    size = 28\n",
    "    images_per_row = min(len(instances), images_per_row)\n",
    "    images = [instance.reshape(size,size) for instance in instances]\n",
    "    n_rows = (len(instances) - 1) // images_per_row + 1\n",
    "    row_images = []\n",
    "    n_empty = n_rows * images_per_row - len(instances)\n",
    "    images.append(np.zeros((size, size * n_empty)))\n",
    "    for row in range(n_rows):\n",
    "        rimages = images[row * images_per_row : (row + 1) * images_per_row]\n",
    "        row_images.append(np.concatenate(rimages, axis=1))\n",
    "    image = np.concatenate(row_images, axis=0)\n",
    "    plt.imshow(image, cmap = mpl.cm.binary, **options)\n",
    "    plt.axis(\"off\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure more_digits_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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QOa4yti4ceOA2u+3docUSVfnieyIupWP3nu1axOPpNSQjXyfzcrbv/baa2v87Oijjy7mMnNyxNDMzMzMgGYaMZSll14aCN/K1S9LOXn6F8JRuXq9qcK30pSDACFioL50pYgU5srzKWXuj8b+1OaNN94Awhi9xx57DIDPP/88uYxycW644YaMy+qIulOnTkBmv6+///4bSOfItHwUURs6dGjG+crfUT9DqFmdX2l6jOIja1GE7NtvvwXgmmuuAUJU/K233gLgl19+ATKjK+oysMsuuwA1+5WmmapNdf+Uf5m9OwA1I4aifEX9zSCzOt3KR1Gknj17JuepL11jbLDBBkAYtdZUTJ48udJLKJjGdmr3aa+99gJyvy6fe+45IORRDx48GAifd7feemvGdeNeqwMHDizNHYg4YmhmZmZmQDOPGErv3r2B0CNM397jnI9hw4YBocJR+/yV6m133333AZkd0XVEEh+NFlt81KPTqoArhuyO8PHRUVylGlPEUEdXqsSbY445ksuoX5SO4tZYYw0gRFcXXHBBABZddNHkOqre7tChQ0PvTtnUVYW81FJLAeF+ptEss8wChB59ig5CmPiRL89Kr0PlWsUTXuaff34AevToUdwFl4Ci1K+99hoAffr0AcL90XM6ngzSuXNnIOSVandD/v33XwDuuOOO5Dzll+pvbpVT145LITsyquJVH1jlGFa7e+65p9JLKJh6S2o6U/Z7Vfv27ZPTL730Usa/up9ffPEFEF7vei+8+uqrS7XsnBwxNDMzMzPAEcMMK6+8MhB6BsW9lPbYYw8ALr30UgDef/99AB555JEyrjBQNCvuY6Wji759+xbt96hPYq5+aqpwjftrNZYqUtu1awcU1qtp8cUXB0JfuhVWWAEIneELoQkCcZRKUbZqoGrEfLlj2TmHaaSqb+VJxlN4lGukqL4ea70u5513XiBML4ojhjovzfQ6VtRPuxii1586Jqy33nrJz5SXpH6U2ZXoek7HzwG9ZjRTvhpm6eaLnD399NNAdcxK1meMeudCqErefPPNAZhtttnqvB1NMoqr06udnttQXX0MNYtdNQqKwuv9TBPBWrdunVxHtQFPPfUUECKH2fmImlwVz9PWc0c1EqXgiKGZmZmZAf5iaGZmZmbTeSs5B4WAd9111+S8AQMGACE5XNsXCuuqiKGStAVRjFY62kI+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iWaN8s033wDQu3dvAJ5//nkAWrQIE5BWXnllAK666qoyr87MrG7PPvssAJtvvjkA888/PwD7778/AAsuuGBlFtbEOWJoZmZmZgC0+O+//yq9hlxKsqjLLrsMgCOOOAKAX375peDrPvbYYwBstNFGxV+YJX799Vcg5MLNOuusyc9effVVIDxu119/PQAbbrghAG3btq3z9hdaaCEAevXqBcCaa65ZjGWnhqqODz/8cADuv/9+APQ6P/3005PL6r7r71dNdH922mknAB544AEg7AYsuuiilVmYFcXo0aOT0w8//DAAb7zxBgDvvvtuxmXXWWcdAO69997kvFatWpV6ian022+/AdCtWzcAvvjiCyBE3gCWWGKJci+r3rSbt/322wOw7777AnDyyScDMMccc1RmYU1Pi1xnOmJoZmZmZkAzixj+8MMPAKywwgpAyMMqxDzzzAOESFb37t2LvDoDOPLIIwE488wzS/p7Zpjh/4+JVlxxRQB23HFHIESgAJZccsmSrqEUnnvuOQDWW2+9jPP1Or/hhhuS8+L7Wm2mTp0KwLLLLguEyIjyhQcMGFCZhVmDfP/990B43O65557kZ3rv7dy5c8Z1nnrqKSDsMsSVqW+//XbpFlshX375ZXL6u+++y/hZ69atAXjiiScA2GOPPYDwN3nxxReTy84111ylXGaDvf/++8npVVddFYANNtgACDsCet+2onHE0MzMzMzya1ZVyfPOOy8AJ5xwAhDysJSX0a5dOyD3BIiffvoJgIceeghovhHD+G/z+++/AzBmzBgALrnkkozLbrXVVgBcc801Bd/+7bffXudlVJmmqtp84gjCO++8A4TH8bXXXgPgzTffzPh3lVVWSa5TTRFD5RbuvPPOQIgQivp+Kbey2inHKDti+O2331ZsTZV29tlnA/DXX38BIWqmXNyYXhvKyaw0TeH5+OOPARgyZEjyM+WE6/1b9Jpee+21gcypPsOHDwfguOOOK82CS0DvQRdeeCFQ83Movn/ZPxs6dChQM1K6yCKLAOE5kUZ//PEHAHvvvXdynt6Hb7nlFqDpRgq1i6mdyFNOOQUI72dy0kknJaePOuqokq+raf61zczMzKze/MXQzMzMzIBmVnySrWPHjgC8/vrrQNiaVEg/l0mTJgGw1FJLlXh16fDoo48CcMcddwBh2xjCtmzcNDm23HLLAfVLBNffVy0pdBsxbSMuvPDCBd+uqNWNHuvsLZl99tknOa32RtXg2GOPBcJWxJZbbgnApZdeChTWyqcaKfVgu+22A2DXXXcF4LrrrqvYmkpJBRfxe9TTTz8NhHSBadOm1Xk7M844IwBLL700ULlijUceeQQIW8l9+/YFMt9n6qLt4hEjRiTnqSXLRx99VIxllsUFF1wAhGEK2eLWXTvssAMQ2qjFhSkQUknU9meXXXYp7mKLSKkCI0eOTM5TIUpTbTulIsHDDjsMgBdeeAHI/1ka22233YD6pWjVwsUnZmZmZpZfs44Y3nbbbUBomqnIYW2UrL388suXbmEV1L9/fwAmTJgAZLY5yDb33HMD0K9fPyA0TFYBxGyzzVaydTbUjTfeCIQ1i9aq6AuEEYlpte666yan9dxVsrmKpNq3b1/+hZXRZ599BsDiiy8OhKhKHClqSGS5Ur766isgtBL68MMPM37+888/A6FFC4TokF5/r7zySsG/TxGZXAV35aA2JIceeigAZ5xxBlC/Iqnx48cDocUJhEb22nnQe1UaqRhS913FGGo506ZNGyAUS8bn6XWviKva2OjnelzT+F78559/AiG6G4+iffDBByuxpJJSSyYIQwX0fUKP1zbbbAOE5792PlSEA6HgTg3fGzmm1xFDMzMzM8uvWbWryaa8JDUD1lGXjkBzUT7LrbfeWuLVld7kyZOT08OGDQPg6quvBkJrCEUh1A5hpZVWSq4z++yzAyFakzZxi4aDDjoIgFGjRuW8rEZGKe80ze6++24g5KVAyE1R7pEem+ZGUYi4QfLAgQMrtZyCKZdXLTs+/fTTgq+r/EC1cVJkQnlne+65JxCiqzE1+68UjRhV+6iGjDqLc+/k66+/BsIOgUaqpZHapan9lyJo2snKFfH+4IMPgJBTrDZNc845JwDHH388kM5IoShCqui37m9T1bNnz+S0IoX6zqHIebZlllkGCO8PAJ9//jkQXvdxpLxYHDE0MzMzM6CZRwzV+DW7yXFtunTpUtI1lVNcxXfllVcCIbKmo7eWLVuWf2GN9PjjjwOZjX2zK7iUl6FKwGrIGVUVeJwHmU2jsQqp5jv//POBmtEpNUquZmlu6JuLoif5IoWKiulynTp1Sn6WXbk/33zzAeHxzRUpVFRKVauVUoyIljpEaLwlwFtvvQVkNoVOK+1cKa9O0STt0lx88cVAyC+FUM163333AWGH55hjjgFg0KBBpV52o40dOxYIn6mrr756JZdTcrl2cRoycEAjDbVDUAqOGJqZmZkZ0Mwihhqh1Lt3byD0zPv7778Lvo04T6BaTJ06FYDTTz8dCJVOiihAqJJSzkOac1PyUQW17sM///yT97LKyVtsscWA0NctzbTGV199Fag59g7C0Pls55xzDpDZJ0vR0uyKVF1WuSxNtQdipSliAvD888/nvIzydxXZUz50IfT45aJIRSmjDuUy88wzZ/xbbVSNqy4DihiqR6F6PapyG2q+ZlXZfOCBB5Z0rcUwbtw4IDzna8vplyeffBIIz9c4171axO/XOq0dHlWiK3dUufDqMKAqewh5s6V8X3bE0MzMzMyAZhYxVBWPBrXXJ1Io5513HhCiLdVAA7hPO+00IEwX6N69e3KZaowQZtMg8toihaLq1a222goIPQt79OiRXEY9pTQlpdI09UI5hnH0r127dkDILxP1OXvmmWeAUNEcUx6pjkDV+025TzfddFPG77DiiHM5VZkqyrtSdWkhkcIff/wRCLlq2bmocX60nvdNgV7LirrE0ty/UJQ/qtwxUVX5tttuC2RGnPTaHzBgABDeq6rBDTfcAIS87lxTxK699log5FLqua3PqTPPPBOAAw44oKRrLSZFgiE8ftqd0XvByy+/nHEdfabpvbhcHDE0MzMzM6CZRQyVW6hcuyFDhgC5jzTz0WSCanLqqadm/F9TFZpClDDWp08fIESG46MvTQTI56WXXsr4F0LejmaX6vmywAILFGfBBdJ85+y5r5pyAmFGsCadqBpTVax33XUXEDrsA2y66aYADB48GIApU6YAId9UVdBWGvFcbj0/55lnHiDkEcW5RXXRXGxVporyseLpCfW53bTTDpByyGObb755zuuo16OmR2h2LcD2228P5J7TXkqqFC+EIr6ahqJc6WqgXrl6jitiGncSOPHEEwG4/PLLgZr9/jQVRn3+8j3OaaLKcQjvtfq8UTRYkUT1o6xUn1FHDM3MzMwM8BdDMzMzM5uuWW0li5o4a9ste8tMxQtx6X/cXLTarL322kAIWythN264qW3Fata5c2cgbDfEzYK1dfTNN98AcMcddwBw1VVXAblbv0ybNg0ICcJqE6M2EjPMUJ7jKhWOaEtb4q1IjWrU/dMW0/333w+EJHxtk0FIeH7/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QePGjQOgW7duGee/++67QObWVTXSFvJ1110HhPsr2krOteX0wQcfANCuXbsSrrC4PvnkEwDOPfdcAC6++GIA/v777+QyO+20EwA33nhjmVdXHkrN0DbNN998A8Ass8wCwEUXXQRA//79K7C6hlHqwyqrrFLjZ9qyuu222wCYYYb0HBePHz8egKeffhqAsWPHAnDfffeV9PcqJUZ/m5VXXrmkv6+UPv300+T0OuusA4S/Y7m2VLPp80Fb97koteGWW24p2u/V/dVzXa/xYtMW8m677QaEFK/G0nr1t5lvvvkAmHXWWTMud8455wCZxWZWL95KNjMzM7P8qr5aQIm6Sy21FAC9evUqye9RNKWa/fTTT0BIat5zzz2Tn3333XdAzaT2Dh06ACFi+P7775d8naWkZG1FmBXpveyyy4BQvAAhmnLccccB4W9Rzf7555/k9CWXXALUfG4vuOCCAKy77rrlW1gj6X7VFplRBDhNkUJRpPCggw6q9XKKyhdyH7766isA/vjjj7yX0XN8/vnnByofMVRbsNlmmy05b/HFFy/oumolBiGyNNdccxVxdfW36aabAvD555+X9fdOmDABgLXWWgsIhYIQCkSKQZ8bxYoUip4Hku/v17dvXwDuuOOO5DzdZ2u49L1DmpmZmVlFVH3EUHlSe+yxBwCPPPIIAGuuuWajbzs+Cjr77LNzXkZ5IWr1kUbKA7n88suB8DdSFBDyt6s44ogjAJg2bRoAe++9d8nWWWxxmxI9fsOHDwdCxPDII48EYJ555gHg1VdfTa6jaEqlow7FpGbPAEOHDs15GUUS1Ri5Ghx22GFAaDxfrbbZZhsgvGYXWmghILzu9HospG2HIkOHHHJI0ddZbHfeeScQIlvaCYK688f1nFYrHwjP7UrnPSuile/zA0LLNe1M6H1a+YmNoc/HeDCBoonFyLscNGhQo2+jMb744gsA1ltvveQ8tWXSe0F2K59qoM/mDz/8MO9lFEnPzrssBkcMzczMzAyosoihGrXmMmXKFCAcdRXjaCHOp3vxxRcbfDuVcv311wOhYixbXJEeRw/zXaa2y6XRNddck5w++uijATj//PMBOPDAA3NeR1WMEHLt2rZtW6olls3HH38M1J7DtskmmwBhpFo1uOKKKwC48sorK7ySxunXrx8QXqtffvklEHLtllhiiXrfZiG5Voo8tmnT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vKYQMbzllluAEAWMo386L5/FFlusdAurp/PPPx+An3/+OefPN9lkEwCOPfbY5LyZZqr6jzbGjx8PwAsvvACEPHDIHwVXztqKK64IhFzxUtPnr6Lvsf/9739AyAV9//33C77dmWeeGQjRYOWM5rv/afbee+8lp994442cl1E18n777VeWNeXjiKGZmZmZAVUWMbzxxhuT08888wwQIiE6uiomVcEBjBs3DmgauSu5LLvsskCofMu+n9988w2QmcOiqOy1114LhEqqSvfQUpTsn3/+Sc7LFwFtahQNvu2224BQ1aYj+nwVugBjx44FwtGsckj33HPP0iy2CP7++28gc5Rhc5OdL6jHXufXRrmEhx56KAA77LBDKZZYb0cccURy+uabb671so888kipl1MRP/74IwBTp06t93W1izPDDP8f+1G1cqnsscceQN2PVUMdddRRQIiAXiNoVxYAACAASURBVHXVVQDMN998Jfl9xaTPzngHRlXJ2dKSI+qIoZmZmZkBVRYxVFUahMiHcg3atWuXcVnlCM0///zJeSussEKttz9hwgQg5LTEuRA33HADEI6sm5o55pgDqBkp1FHrFVdcAcAXX3xR47p77bUXANtttx0QcpsqRZHehRdeODlPa2yq1AdL1W7K9dltt92AkIP3119/JdcZMmQIAN9++23GbekIV73g0kw5VYXQc/jll18G4LLLLivJmspNj3l27vD2228PhNdlLC2RwXziHPHsvDW95x944IFlXVOpKbdXOa/Z4p7D//77b623pdfwJ598UqTV1e7PP/8EYPXVVweK1/VBk0GUZ3n33XcDMGDAAAC23nrrovyeUlJubL4oIYRJPdq5qzRHDM3MzMwMqLKIYfxtWkckmlrQmCNg5eLU1icqOyLZ1Cg6pL/BSiutBIS8CE2UyEVH8Ntss00pl1gnRTdfffVVIDNK2KFDh4qsqVxGjRoFhOiK+k2qsl6vlzhi+PbbbwNw8cUXA6E/nB7Pueaaq9TLrjflwCqfNZ94mokmnMiUKVOAEHVJ6fSnWh122GHJaVUYK0KoXY111123/AtrJO3avPXWW3kvo3y2c845pxxLKpvsXbBscZRQn3frrbceEHLgNfFEl9X/NS0GMnfRikU7aqoi1r+NpTzxjTfeGAifT+o8UQ0Rw9qm0ChSqLzgBRdcsCxrqosjhmZmZmYG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vvtyMexq89dffwFB+VIShJTDytBrc+CBBwIhJQFCNetHH30EhOdbyl7D+ExPJkqhvIS77rprhiPKjGTVes0114wekwdPymG/fv3yPLpEnnjiCQD2228/IHGs6WjevDkA55xzDpDoA9X3jJ7nSiutBATVW37rRx99FEg9yyc23HBDADp27FjlmKqLFUNjjDHGGAP4h6ExxhhjjFmEp5KBL7/8EqgYzaLlUD2zabEhaVlm1datWwPwzDPPAIkxHpKqZeg++eSTE5b//fffAOy99965HXQtUECqpszGjBkDhBgLCBK9npeez/XXXw+EwguZi0sNTSHrPb3hhhuAEPkyb948AB5++OFom3vuuQcI5uj+/fvnZ7BV0KtXr4z3EZ8u3mabbQBo2bJlxvvNF7JDnH322UCwQohVVlklun/llVcCYapcxXSauorHbolisYEcffTRANx///1ACKtWu00I0+cy76tgbOjQoUD4nCv+BOD3338HQmOCUp5CFm3btq2wLN20sJbnOoKmrqBp75qwzjrrAHDUUUcBsPrqq0ePafpXhTe77LILEAp0dD6vDH2nPf744wBstNFGNR5jOqwYGmOMMcYYwIphWZMcmrn11lsDsNxyy1VYV1eWUtI6dOiQ8Pi+++4LhLDOQqIoC6kNitCRSnD88ccDQUEB2GqrrYBg+lUMjxTDVq1a5XrYWeeiiy6K7qvQQMUlyeHQiuv47rvvomUqaOjduzdQumppKnSsQzj+VaRQzKho5oADDgDCcaqiL72/J510UrTNpptumrCPmTNnAokB9pCo9g8ZMiSbw64xiiGRUihVMB5SnYzid84991wgHLdSVxWDAmGGR4prKaDZGd0mh1bHI3zqihKoGLFSRkVh8dgoNRNQEPsee+wBVK8lnr7fWrRoAWRXKRRWDI0xxhhjDGDFEAgenXLjrLPOAuCKK64A4JZbbgFCUOx///vfaF1dkcgPIdZee20g0fNTaKR6yTOpqJnOnTsDsP/++wMhxqM6LLPMMtkcYl5QeDVUHZAqD0s8ukTbyNdVDkhFjb8eAwYMABKjeooNKYVSwaQUyjOqQPadd9457T7U2vP8888HgpImpLRBiMcoFPIy632S10r+yOq0HpUqKD9tPIpKMwFSa4oZeQeTI0mSFcNSVwmTz7GKp3rggQeA4B2N8+yzzwJBSVMMUSmhgPa4v1vfzVW1xNN3XFxtlAc7OV4vm1gxNMYYY4wxgFviAUElU8ssceKJJ0b3VS1USig8VkqaqpdEvCpZx4HUOCmFUqUUlFwuKNRZ7d8UqFtoJaUmxNt8yW+ikGophPIaKjQ6HvqttnEKui5lj6FUQXnn5CmF8B4X8/OTYhb3RkL4/Mnjm4qpU6cCoXJy8uTJKdeTrwlgp512qv1gs4jCfy+77DIgnJMGDx4crdOzZ0+gYjKEvFZKWdDMCATPYrESVweTq43VujRZMSx1pGhL8br99tsTHt9xxx2j+40aNQKCmnjzzTcDqds7FjtHHHEEUDFZACq2xFOAtgK9dY7OofLtlnjGGGOMMSY9VgxJrxhOmzYtul/odmGZIH+G1JT4lbXQcaDKP6ks8jiUG1tssQUQvFylqBjGURahFMHkK9FUzdqlAsvrU4rIU6j2lXp+3377bbROMSuFQq3pVEkvhUC+OWWWCfmFIailyvnTZ/jzzz8Hwvscr2pNlUxQCNS+T+q3cgfjfkElJEhhkn9Q7fNee+01oLSyClN5guUhjL9P5YiUQyndIq6K6TU48sgjgfDajBs3DoCllloq18PMGpqdkrIdJ/m8rKQNtTzUzF0OsWJojDHGGGPSU6erkqUSJV+hKTNMmXeljiq5tttuOyAxE0lomZqDl6tSmEybNm0AWH755Qs8ksxQZp0q39T95cMPPwRC1euMGTOibWqT5l8sKElASqG8OHfddRdQGiphnLj3E4LXLvncdM011wDw9ddfR8sWLlwIBAVGCQJSDHfYYQegeFTCOKqsVBbjSy+9BMDIkSOjdVTBmeyzmjBhAlBaSmFlyHcoz6G6mZRbFxN5RSvzrcsbrexNzWDp86BOVaWA1P1UHkNlycpLrJxgVWjrvJDc2SbXWDE0xhhjjDFAHfcYqmNG8jy+cvCSr+JLFfWNVTeFOXPmAIm9G3UcqJJZFYzJXRVKHWW7qVel3mtVv5UrynSMe5vk1VJ1ZymhvD8pS1IMVc0XR/5gqYjF6BeWp666yoCUboBHH30UCHmee+65JxAUw+eeew4ozuddHeSfjefAQUiKiHeBKRXiFcfyk1WFqpWTty9nNBMir6GyOMvt+UvlVyanfpuIeF2AztdZmgGwx9AYY4wxxqTHPwyNMcYYYwzgqWSgfKeSFZqr0ExNIev5PvbYY9G6al4/bNgwIBQmSNouF9QG8OSTTwaC+beyVmOljKbfNB0Xtw/EI11KDb1v+oyqaCG52AbSR/bI4F0MrfJmz54NhOl9FdHMmjUrYb1TTz0VSAyA1hSy3muFO6uATFaSUuDff/8FglUAQrixbu+++24gFCLoNYtvU4okT49WNsWs514uBSlVoUIVfYYV4l5KsTXVQdFhiuFSU4r47zSdExQCniGeSjbGGGOMMemxYkj5KoYKuq1Om7uzzz4bCIphq1atgHBluvLKK+dhxLknuT3RZ599BoTihXJBgcHbbLMNAPPnzwfg6aefjtYppciH6iLF8IsvvqiwLFllLIeAbwjB1oqlEn379gVg+PDheR9TbZEa2K1bt2iZArylkur5br/99gl/33HHHdE25aCkKb5GymG8jZ4o0u/vrJPcOlEKew5bxRWUuXPnAqG1ZzyeSt/VQ4cOzca/smJojDHGGGPSU6cDrssVtdWZN28eEDxV8tdVFiwqfvnlFwB+//33XAyxYMhnudlmmwHlpxQKKWZSCnXlWY4qYZyNN9444RZCS7XmzZsDIfy7XHj22WeB8DlX+7w+ffoUakg1RrMa8v7GSY5TUhi9goP32GMPAM4///xoHb3HpRZ0Hkeqp5TCuGJYDopoJrz33ntA+SqGCn5PFUmz+eab5/z/WzE0xhhjjDGAFcOUrLDCCoUeQq1QJaOazct/csoppwAh4DoVquLUNqpoLNcrsnJF3sIePXoAQUXq379/wcZULMhbWG6vicJxhZQzhbiXAuPGjQPgp59+AhLHLq90Mttuuy0AV111FZDY4vGee+4BQhV3KSKFUM0GTODjjz8GwmxAuXHfffcB8NFHH1V4TIH2Xbp0ydn/t2JojDHGGGOAOq4YqvInmVJsEQah0bgUEWU8qUVWMlOnTo3uK6+wcePGAFx77bU5G2chkGfytddeA8o3t1AtpHRsK7dQTenrIjfddBMAN954IxBaw5XyaxJvmSW/1dJLLw3AKqusUpAxZYIUINGrV6/ofr169SrdVjmtev4AP//8cxZHlznKKJT6F29vl+wXlFLYtm3btPurbutEk3tUSd+9e3cgzLqp/WqqvEEdB8oY1Xf2NddcAySmKgBsscUW0f18ZAtbMTTGGGOMMUAdVwzlxSsX5C8T6oigK275eKZPnw5Av379KuxDVybl5i2UL0NV1qmqH0sZVaCrUrPcfHQ1Ra8HwMiRI4HwmnTu3LkgY8omt912W4Vl8gUrh7WUadOmTbXXVabdX3/9lavh1BophcldTFJlElZFXFlM7pJSSqiKXp1qNKvRs2fPaJ1in7WLdxM64YQTgHB+EepaIgVfNQAQMlU1k5W8bfLfca9scl5pLrBiaIwxxhhjAP8wNMYYY4wxi6jTU8nlhkz1MqMr+mHvvfeuclvJ+hdffHGORldYVJQh1l133QKNJDfIrC/TstqhlXJcRybEixc07XPkkUcCFeNdSonPP/8cSGz/1qBBA6DiMV5KKNBXBSQbbLBBldsoykNt0v7999/osWKxwiRPIdcGFaqU8vRxnPHjxwOw+OL/r0vpe0pTshBawKk1ohoTFAvNmjWL7h9++OEA3HrrrQnr1CZgXlF5O+64IxCipxTNlC+sGBpjjDHGGAAWK9Im3HkZ1Omnnw6EgNStt94aCMbQ+vXr52MYWUPKyAMPPADA5ZdfDgQjqwzdCxYsAEJBBoQ2WuWKokkmTpwIwLRp04DUUQKlwsMPPxzdV0FFixYtgGBuL+WWYLVBCoMCjgE6deoEwOjRowsypmyi4jDNCkBom1VsES01BVqN+QAAIABJREFUYdasWUA4B6sgAeCoo45KWFft84YOHQqEIjudz6F4VOF0xSfxuBpFlyiCplyUwXTMnDkTCLM2M2bMABIDyhUrpsi1v//+G4CGDRsCodCyGM5vKn5q2bIlED6HyQUkSy4ZJmjXXnttIKjcAwcOBIJSXllUUZZZLNVCK4bGGGOMMQao44rhqFGjgNBa5owzzgCC0mbKB/kvFVfz2WefFXI4GTF//nwgMdJDV9ADBgwAYPDgwfkfWB658sorAZg0aRIQ3t8hQ4YAwWMJIbKnGNSFmqLjVOeot99+GwgKCgS/YdeuXfM8uuyjSK14u68ffvgh5bqaBZByGPd9mdIj7hEdNmwYEM5jv/76a8LyuDpcLEj5vfrqqwEYO3YsEHzeUhQBjjnmmDyPLi1WDI0xxhhjTHrqtGJoyhtdXQKceeaZQKhWzUdboVwhL+k222wTLVOLvzvvvBOA9dZbL/8DyyN6DTp27AgE9Ui37du3L8zAsox8kap8FPFq8+HDh+d1TMaYssGKoTHGGGOMSY9zDE3Z8v3331dYVg7t0LbaaisA/vnnnwKPpHDoNfjmm28KPJL8Il9puXtIjTGFw4qhMcYYY4wB7DE0xhhjjKmL2GNojDHGGGPS4x+GxhhjjDEG8A9DY4wxxhizCP8wNMYYY4wxgH8YGmOMMcaYRfiHoTHGGGOMAfzD0BhjjDHGLMI/DI0xxhhjDOAfhsYYY4wxZhH+YWiMMcYYYwBYstADyCe//fYbAFOnTgVg9OjRAKy44ooAvP322wDMmTMHgN69e0fbdu/eHYDFF/dvaWOMMcbklj/++AOAww47LFo2duxYABo3bgzA559/nvX/6185xhhjjDEGgMX+97//FXoMqch4UJ9++ikA559/frTsqaeeAuCnn34CoH79+gAstdRSQFAUl156aQB+//33aNvx48cDsMcee2Q6tILz3nvvAfDyyy9Hy/r06VOtbVdaaaXo/iuvvALAJptsksXRGWPqOq+99lp0XzM5V1xxBQAzZ84E4Pnnnwdg1113ze/gTN4ZPHgwAAMHDgSgVatWAPTr1w+ALl26FGZgOebNN98EoE2bNhUek2L42WefZfIvFku10IqhMcYYY4wBylgx3GuvvYBET+CGG24IQMOGDQHYfvvtAdh4440B+PnnnwFYZpllANhvv/2ibbXOmDFjMh1a3vn444+BMPbrr78eSPQmLLZYyguHSmnZsiUAt9xyCwDbbLNNJsM0xlSTWbNmRfdHjhyZ8Ngdd9wBwJdffpmw/JprronuH3/88QCMGDECgEGDBgHhM/3iiy8CUK9evWwOOy0//PADACeddBIAEyZMiB6bN29eym1WXnllANZZZ520+73ooosA2HHHHQFYZZVVMh+sqREDBgwA4JBDDgFg8803r/a28tituuqqAMyfPz/hcanFEydOzHicxcTff/8NwBFHHAHAgw8+WGGd5s2bA/DBBx9k8q+sGBpjjDHGmPT4h6ExxhhjjAHKeCpZ0yjrrbderfexxRZbRPc//PBDAL799lsAVlhhhQxGlx9++eUXANq3bw/A5MmTEx6Pv/e1mUoWl112GQBnnnlmrfdREzTu//73v9VaD8Lz++6774BgZr7qqqsSHt9///2jbWTuLSemT58e3R8yZAgA9913HwDPPfccUJxmfhUgPP7440CYFtX7KS6++GIA+vfvX+19//rrrwBccskl0TIVaJ133nlAsJ0UChXCjRo1CgjvHQSrSDbQ1PH3338PwLLLLpu1fVeGpsoOPfTQam+jz3d1zl0H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HWXWrFkA7LHHHgB8/PHHAKy22mrROhMmTACgVatWeR6dMaa6yE+YiokTJ+ZxJKY26Fx8xhlnRMtGjx6dsM5pp50GwPDhw/M3sDqMFUNjjDHGGAP4h6ExxhhjjFlE2U8lv/HGG9H9Nm3aZG2/Dz74IBDiEOJTkKZ4+eKLLwDo0KEDAJ988gkQjOvfffddtG6nTp0A+Oijj/I5xKwyb948AI477jgAHn300QrrXHjhhQAMGDAgfwPLEjfffDMAZ599NgBnnXUWAP369avxvn799dfo/qeffgrAeuutB8Aqq6yS0ThN9tEU8vPPP1/hsQsuuCDPo6k948ePB2CNNdYA4IEHHki5no5FgCZNmgDwzTffANC6dWsANt1005yNM1to6vjQQw8F4LXXXku77rrrrgvAlVdeCcB2222XsG2pot8iU6ZMAWDxxVNrdM2aNQPg7rvvjpY1btwYgFVXXTVn47NiaIwxxhhjAFjsf//7X6HHkIqMB/XMM88A0LVr12iZVL13330XgKWWWqrG+73//vsBOOqoowA44IADABg1alStx1oKDBs2DICLL744WtauXTugNJ77s88+C8BBBx0EwIIFCxIe32GHHQB45ZVXomW6Kpd6VEpcf/31QPgcPPHEE1Vuc8011wBwwgkn5G5gWULq5o033ggEpVdX4pMnT672vn7//XcADjnkkGjZ448/DsAdd9wBQPfu3TMcsckW6ZTC3XbbLbpf14pOvv/+eyB8dtOpjoXk9NNPB4L6J/S503cMBKVQz+Owww5L2KYUi1FefPHF6L5+P2gGa4kllki5zT///FPh8SOOOAKAK664AshYOUyZ8WTF0BhjjDHGAGWoGD799NNAuMKPe8aEFIJ69erVeP9jxowBwq/2+vXrA7D//vsDQWEodf79918gvI733XcfAKuvvnq0jtSozTbbLM+jqx6fffZZdH+fffYBYMaMGQnryJvz8ssvA9ClS5fosffffx8oDcVQSmfPnj2B4D2Sby7dFWkcHcvyHJ500klA7ZT1XLP++usD4Yp75ZVXBuC5554DwvtaHaQeb7/99tGy9957D6h7iuGff/4JhNdVbLTRRoUYTgJSCNPF0xTpd1nGyJP30EMPRcvkR9T56sMPPwRg7733BhLPfYVAYwbYcccdE5bJJyi1L/65S4f8lfH9QlAW+/btGy2TMlksSCk8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\n",
      "text/plain": [
       "<Figure size 648x648 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(9,9))\n",
    "example_images = X[:100]\n",
    "plot_digits(example_images, images_per_row=10)\n",
    "save_fig(\"more_digits_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Binary classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_5 = (y_train == 5)\n",
    "y_test_5 = (y_test == 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**: some hyperparameters will have a different defaut value in future versions of Scikit-Learn, such as `max_iter` and `tol`. To be future-proof, we explicitly set these hyperparameters to their future default values. For simplicity, this is not shown in the book."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SGDClassifier(alpha=0.0001, average=False, class_weight=None,\n",
       "       early_stopping=False, epsilon=0.1, eta0=0.0, fit_intercept=True,\n",
       "       l1_ratio=0.15, learning_rate='optimal', loss='hinge', max_iter=1000,\n",
       "       n_iter=None, n_iter_no_change=5, n_jobs=None, penalty='l2',\n",
       "       power_t=0.5, random_state=42, shuffle=True, tol=0.001,\n",
       "       validation_fraction=0.1, verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import SGDClassifier\n",
    "\n",
    "sgd_clf = SGDClassifier(max_iter=1000, tol=1e-3, random_state=42)\n",
    "sgd_clf.fit(X_train, y_train_5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.96355, 0.93795, 0.95615])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.96355\n",
      "0.93795\n",
      "0.95615\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import StratifiedKFold\n",
    "from sklearn.base import clone\n",
    "\n",
    "skfolds = StratifiedKFold(n_splits=3, random_state=42)\n",
    "\n",
    "for train_index, test_index in skfolds.split(X_train, y_train_5):\n",
    "    clone_clf = clone(sgd_clf)\n",
    "    X_train_folds = X_train[train_index]\n",
    "    y_train_folds = y_train_5[train_index]\n",
    "    X_test_fold = X_train[test_index]\n",
    "    y_test_fold = y_train_5[test_index]\n",
    "\n",
    "    clone_clf.fit(X_train_folds, y_train_folds)\n",
    "    y_pred = clone_clf.predict(X_test_fold)\n",
    "    n_correct = sum(y_pred == y_test_fold)\n",
    "    print(n_correct / len(y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.base import BaseEstimator\n",
    "class Never5Classifier(BaseEstimator):\n",
    "    def fit(self, X, y=None):\n",
    "        pass\n",
    "    def predict(self, X):\n",
    "        return np.zeros((len(X), 1), dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.91125, 0.90855, 0.90915])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "never_5_clf = Never5Classifier()\n",
    "cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_predict\n",
    "\n",
    "y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[53057,  1522],\n",
       "       [ 1325,  4096]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "confusion_matrix(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[54579,     0],\n",
       "       [    0,  5421]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_perfect_predictions = y_train_5  # pretend we reached perfection\n",
    "confusion_matrix(y_train_5, y_train_perfect_predictions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7290850836596654"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score, recall_score\n",
    "\n",
    "precision_score(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7290850836596654"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4096 / (4096 + 1522)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7555801512636044"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7555801512636044"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4096 / (4096 + 1325)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7420962043663375"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import f1_score\n",
    "\n",
    "f1_score(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7420962043663375"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4096 / (4096 + (1522 + 1325) / 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2412.53175101])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_scores = sgd_clf.decision_function([some_digit])\n",
    "y_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold = 0\n",
    "y_some_digit_pred = (y_scores > threshold)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "threshold = 8000\n",
    "y_some_digit_pred = (y_scores > threshold)\n",
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,\n",
    "                             method=\"decision_function\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import precision_recall_curve\n",
    "\n",
    "precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure precision_recall_vs_threshold_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):\n",
    "    plt.plot(thresholds, precisions[:-1], \"b--\", label=\"Precision\", linewidth=2)\n",
    "    plt.plot(thresholds, recalls[:-1], \"g-\", label=\"Recall\", linewidth=2)\n",
    "    plt.legend(loc=\"center right\", fontsize=16) # Not shown in the book\n",
    "    plt.xlabel(\"Threshold\", fontsize=16)        # Not shown\n",
    "    plt.grid(True)                              # Not shown\n",
    "    plt.axis([-50000, 50000, 0, 1])             # Not shown\n",
    "\n",
    "\n",
    "\n",
    "recall_90_precision = recalls[np.argmax(precisions >= 0.90)]\n",
    "threshold_90_precision = thresholds[np.argmax(precisions >= 0.90)]\n",
    "\n",
    "\n",
    "plt.figure(figsize=(8, 4))                                                                  # Not shown\n",
    "plot_precision_recall_vs_threshold(precisions, recalls, thresholds)\n",
    "plt.plot([threshold_90_precision, threshold_90_precision], [0., 0.9], \"r:\")                 # Not shown\n",
    "plt.plot([-50000, threshold_90_precision], [0.9, 0.9], \"r:\")                                # Not shown\n",
    "plt.plot([-50000, threshold_90_precision], [recall_90_precision, recall_90_precision], \"r:\")# Not shown\n",
    "plt.plot([threshold_90_precision], [0.9], \"ro\")                                             # Not shown\n",
    "plt.plot([threshold_90_precision], [recall_90_precision], \"ro\")                             # Not shown\n",
    "save_fig(\"precision_recall_vs_threshold_plot\")                                              # Not shown\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(y_train_pred == (y_scores > 0)).all()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure precision_vs_recall_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_precision_vs_recall(precisions, recalls):\n",
    "    plt.plot(recalls, precisions, \"b-\", linewidth=2)\n",
    "    plt.xlabel(\"Recall\", fontsize=16)\n",
    "    plt.ylabel(\"Precision\", fontsize=16)\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "    plt.grid(True)\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_precision_vs_recall(precisions, recalls)\n",
    "plt.plot([0.4368, 0.4368], [0., 0.9], \"r:\")\n",
    "plt.plot([0.0, 0.4368], [0.9, 0.9], \"r:\")\n",
    "plt.plot([0.4368], [0.9], \"ro\")\n",
    "save_fig(\"precision_vs_recall_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold_90_precision = thresholds[np.argmax(precisions >= 0.90)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7816.1555236825225"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "threshold_90_precision"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_pred_90 = (y_scores >= threshold_90_precision)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9000380083618396"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.4368197749492714"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ROC curves"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve\n",
    "\n",
    "fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure roc_curve_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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J0/mrLPO0r1tRESyVCSbOXJzjJxmzaBp07BDkYh44403aNWqFQsXLgSgT58+Sm5ERLJYUgmOme1jZuPMbL6Z/cPMDg+WDzGzY9MTYvLycgx+9ztfRKpg+/btDB8+nO7du9OiRQsaN87KGUpERCROwgmOmbUFPgIGA1vwE3HWDVa3AbJmXoRaGn8jKfDFF19w4okncs899zBkyBDeffddDjvssLDDEhGRBCQzBmcCsBI4AygCtsesWwBkTXNJ0badcOml/sGkSeEGI9XWSy+9xBdffMFLL71Ejx49wg5HRESSkEyC0wno55zbYGbxtwleC/wkdWFVTbMGdaD2/mGHIdVQUVERn332GR06dGD48OH069ePfffdN+ywREQkScleRVVSzvKm/DAJZ+hyc4AxY8IOQ6qZxYsXU1BQwIYNG1ixYgX16tVTciMiUk0lM1jlA6B/OesuAN6tejipkasbrkkSnHM8+OCDHHfccXz33Xc899xz1KtXL+ywRESkCpJpwflfYLaZvQY8i7/lzClmdgVwEdA5DfHtkZwcg379/IOpU8MNRrLa1q1bKSgo4NVXX6Vbt248/fTTNG/ePOywRESkihJOcJxzc83sIuA+oHuw+B7g38BFzrkFaYhvj+SYQZs2YYch1UCdOnWoX78+99xzD1dffTU5OboCT0QkCpIag+Oce8nMXgaOAFoAXwMfOed2pSO4PZWbYzBqVNhhSJYqKSnhzjvv5MILL+SQQw5h6tSpmkdKRCRikp6qwfkpk5emIZaUydG5Ssrx1Vdf0a9fP+bNm8eOHTu49dZbldyIiERQwglO0D1VIefc81ULJzVycwwKCvyD6dPDDUayxsyZMyksLKS4uJhJkyZRWFgYdkgiIpImybTglJcpuJjfsyLByTGD9u3DDkOyyIsvvkjPnj1p164d06dPp23btmGHJCIiaZRMglPWPeqbAmcBPYGs+TpcOy8HRowIOwzJArt27SInJ4du3boxduxYhg8fTt26dSt/ooiIVGsJXzLinFtWRlnonLsJ+AN+jqqskKtBOAJMnTqVjh07smnTJvLz87n55puV3IiI1BCpuib2L8A5KdpWleXlGFxwgS9S4xQVFVFYWEj//v2pX78+mzdvDjskERHJsKSvoirHsfgZxrNCjhkcf3zYYUgIFi1aREFBAZ9//jm33HILo0aNIi8vVR9zERGpLpK5iuqGMhbXBo4EegBPpCqoqsrLNbjuurDDkBBcd911FBUV8dZbb3HqqaeGHY6IiIQkma+2d5SxrAT4CrgXGJ2SiFIgV3ejrVG+/vprnHM0a9aMyZMnU7duXZo1axZ2WCIiEqJkEpz8MpbtyLa7GAPkGnBOMCRoxoxQY5H0+utf/0rfvn059thjefnll9lvv/3CDklERLJAQk0dZlYbuA040jm3LaZkXXIDQQvOr37li0RSSUkJo0ePpnPnztStW5eRI0eGHZKIiGSRhFpwnHPbzexqYFaa40mJFeuLYPjVYYchabJmzRp69+7N22+/Tb9+/Xj44Ydp2LBh2GGJiEgWSWawyhLg8HQFkkqHtdwr7BAkjfLy8lizZg2TJ0/mmWeeUXIjIiI/kkyCcwNwo5l1SVcwqVI7LwfOPNMXiYRt27Zx7733snPnTpo3b87HH3/MxRdfHHZYIiKSpZIZZPwUsDfwJzPbAqxl93monHOuTSqD21M5ZnD22WGHISny2WefUVBQwKJFizj00EPp3r277m0jIiIVSuYs8Xd2T2iyVl6OwZAhYYchKTBlyhSGDBlCnTp1ePXVV+nevXvYIYmISDWQcILjnCtIZyCplKO5qCLh5ptvZty4cZxyyik8++yzugRcREQSVmGCY2YrgB7OuSUZiiclcnOALsFQoblzQ41F9twFF1xA7dq1GTlyJLm5uWGHIyIi1UhlLTgHAXUyEEdK5eXkQK9eYYchSXLOMXHiRFauXMl9991Hhw4d6NChQ9hhiYhINRTJkZpF23bCoEFhhyFJWL9+PZdeeimvv/4655xzDjt27KBWrVphhyUiItVUIpeJV4uBxbF2uWoXco02b9482rVrx5w5c5g4cSKvvPKKkhsREamSRFpwRpvZ+gTqOedcYVUDSoUWDetC6UzS8+aFGYpUYuPGjZx33nnss88+vP766xx99NFhhyQiIhGQSILTHtiWQL2saTbJMeCSS8IOQyqwfv16mjZtSqNGjXj99ddp3749DRo0CDssERGJiES6qM5zzrVKoByc9mgTlGPmExwlOVlpxowZtGnThieeeAKAk046ScmNiIikVDJTNVQbZsCOHb5I1ti6dStDhw7l3HPP5aCDDqJz585hhyQiIhGV8QTHzJqY2ctmttnM/mlmfcqpd72ZLTWzTWa20syuT2If8Otf+yJZYdmyZRx//PE88MADDBs2jIULF3LIIYeEHZaIiERUGJeJPwRsB/bBj++ZaWZLnHMfx9Uz4GLgQ+BnwBwzW+2cm17ZDnIMGDgwtVFLlSxfvpwvv/yS1157jbPOOivscEREJOIqTHCccylt4TGz+sAFwJHOuSJgvpnNAPoDI+L2PT7m4TIzexU4EUggwTHo1y91gcse2bRpE3/729849dRT6datGytWrKBhw4ZhhyUiIjVApruoDgVKnHOfxSxbAhxR0ZPMzICTgfhWnjLlGLBliy8Sir///e906NCBW2+9lTVr1gAouRERkYzJdBdVA2Bj3LKNQGVnvtvwydikslaa2eXA5QC1W7Zm1cqVbLj2QgAW33dfFcKVZO3atYsXXniBJ554gsaNG3P77bezbNkyli1bFnZoAhQVFTFP94bKGjoe2UXHI1oyneAUAXvFLdsL2FTeE8zsKvxYnJOdc2Xej8c59zjwOECdnxziDv7Zwez9298CcGrpDf8k7ZxznHfeecyYMYNzzz2Xp556ig8//FDHIIvMmzdPxyOL6HhkFx2PaMl0gvMZkGdmhzjnPg+WtaOcriczG4Afm3OKc+7LRHeSY6bJNkNgZpx88smcfvrpDBkyxF/NJiIiEoKMJjjOuc1m9hIwxswG4q+iOhc4Ib6umfUFxgGdnXMrktlPjgEbg56wRo2qGLVUZOfOnYwZM4bjjjuObt26cd1114UdkoiISCg3+hsC5APrgOeAwc65j83sZDMriqk3FmgKvG9mRUF5NJEd5JjBuef6ImmzevVqOnfuzO23386bb74ZdjgiIiLfy/h9cJxz3wDnlbH8Hfwg5NLHrfZ8H8DQoXv6dEnAK6+8woABA9ixYwdTp06lb9++YYckIiLyvTBu9Jd2327ZDuefH3YYkTV//nx69OjBMcccw/Tp02ndunXYIYmIiOwmknNR/WTvfFi/3hdJmeLiYgBOPPFEnn76aRYuXKjkRkREslIkExwD6NnTF6ky5xyTJk2iVatWfP7555gZhYWF1K5dO+zQREREyhTJLioAhg8PO4JI+O677xg8eDDTpk3jtNNOo379+mGHJCIiUqlIJjhmwNlnhx1GtffBBx9QUFDAqlWrGDt2LCNGjCA3NzfssERERCoVzQQHg7Vr/YOWLcMNphqbNGkS27dv5+233+bEE08MOxwREZGERXMMjgEFBb5IUv773//yySefADBhwgQWL16s5EZERKqdiLbgACNGhB1GtfPWW2/Rr18/mjVrxuLFi8nPzyc/Pz/ssERERJIW3Racrl19kUrt3LmTUaNG0aVLFxo1asTUqVPJyYnkR0NERGqIiLbgGKxe7R/sv3+4wWS59evXc95557FgwQIGDBjAxIkTdaWUiIhUe5FMcDCgf3//+7x5YUaS9Ro1akTDhg2ZNm0avXv3DjscERGRlIhkgmMAI0eGHUbWKi4uZsyYMVx77bU0b96cN954AzMLOywREZGUiWaCYwZduoQdRlb65JNP6NWrFx999BFt27alsLBQyY2IiEROJEeSGsCKFb4I4Kdb+P3vf8+xxx7L2rVrmTVrFoWFhWGHJSIikhbRTHAMGDDAFwHg3nvvZeDAgRx//PEsWbKErrrCTEREIiySXVQAjB4ddgRZYdeuXeTk5NC/f3/MjKFDh2q6BRERibzotuB06uRLDbVr1y7uuusuunTpws6dO2nevDnXXHONkhsREakRopngYLBsmS810Lp16+jWrRs33HADTZo0YevWrWGHJCIiklGR7KIyA664wj+oYffBmTt3Lv3792fDhg08+uijXH755bpKSkREapxIJjgAjBsXdgQZt3PnTq688koaN27MnDlz+PnPfx52SCIiIqGIZIJjZnDCCWGHkTH/+te/aN68Ofn5+cycOZN9992XevXqhR2WiIhIaCI6BgdYutSXiHvxxRc56qij+O1vfwtA69atldyIiEiNF80Ex4CrrvIlooqLixk8eDA9e/akTZs2DB06NOyQREREskY0u6gwuOuusMNIm2XLltGzZ0+WLl3KDTfcwO23307t2rXDDktERCRrRDPBMaBjx7DDSJucnByKi4uZPXs2Z5xxRtjhiIiIZJ1odlEBLF7sS0Rs3LiRiRMn4pzjkEMO4dNPP1VyIyIiUo5ItuAAMGyY/xmB++C89957FBQUsHr1ajp16kS7du3Iy4vuoRMREamqSLbgbNq6E+67z5dqbNeuXYwfP56TTjoJ5xzvvPMO7dq1CzssERGRrBfJZoDG9WvD4e3DDqPK+vfvz7Rp07jwwgt5/PHH2XvvvcMOSUREpFqIZIJjAO+/7x9U48HGffv2pVOnTgwaNEjTLYiIiCQhmgmOAddf7x9UozE4O3bs4JZbbmHvvffmxhtvpFu3bmGH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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_roc_curve(fpr, tpr, label=None):\n",
    "    plt.plot(fpr, tpr, linewidth=2, label=label)\n",
    "    plt.plot([0, 1], [0, 1], 'k--') # dashed diagonal\n",
    "    plt.axis([0, 1, 0, 1])                                    # Not shown in the book\n",
    "    plt.xlabel('False Positive Rate (Fall-Out)', fontsize=16) # Not shown\n",
    "    plt.ylabel('True Positive Rate (Recall)', fontsize=16)    # Not shown\n",
    "    plt.grid(True)                                            # Not shown\n",
    "\n",
    "plt.figure(figsize=(8, 6))                         # Not shown\n",
    "plot_roc_curve(fpr, tpr)\n",
    "plt.plot([4.837e-3, 4.837e-3], [0., 0.4368], \"r:\") # Not shown\n",
    "plt.plot([0.0, 4.837e-3], [0.4368, 0.4368], \"r:\")  # Not shown\n",
    "plt.plot([4.837e-3], [0.4368], \"ro\")               # Not shown\n",
    "save_fig(\"roc_curve_plot\")                         # Not shown\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9611778893101814"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import roc_auc_score\n",
    "\n",
    "roc_auc_score(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**: we set `n_estimators=100` to be future-proof since this will be the default value in Scikit-Learn 0.22."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "forest_clf = RandomForestClassifier(n_estimators=100, random_state=42)\n",
    "y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,\n",
    "                                    method=\"predict_proba\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_scores_forest = y_probas_forest[:, 1] # score = proba of positive class\n",
    "fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure roc_curve_comparison_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, \"b:\", linewidth=2, label=\"SGD\")\n",
    "plot_roc_curve(fpr_forest, tpr_forest, \"Random Forest\")\n",
    "plt.plot([4.837e-3, 4.837e-3], [0., 0.4368], \"r:\")\n",
    "plt.plot([0.0, 4.837e-3], [0.4368, 0.4368], \"r:\")\n",
    "plt.plot([4.837e-3], [0.4368], \"ro\")\n",
    "plt.plot([4.837e-3, 4.837e-3], [0., 0.9487], \"r:\")\n",
    "plt.plot([4.837e-3], [0.9487], \"ro\")\n",
    "plt.grid(True)\n",
    "plt.legend(loc=\"lower right\", fontsize=16)\n",
    "save_fig(\"roc_curve_comparison_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9983436731328145"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "roc_auc_score(y_train_5, y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9905083315756169"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3)\n",
    "precision_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8662608374838591"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multiclass classification"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5], dtype=uint8)"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.svm import SVC\n",
    "\n",
    "svm_clf = SVC(gamma=\"auto\", random_state=42)\n",
    "svm_clf.fit(X_train[:1000], y_train[:1000]) # y_train, not y_train_5\n",
    "svm_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 2.92492871,  7.02307409,  3.93648529,  0.90117363,  5.96945908,\n",
       "         9.5       ,  1.90718593,  8.02755089, -0.13202708,  4.94216947]])"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "some_digit_scores = svm_clf.decision_function([some_digit])\n",
    "some_digit_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argmax(some_digit_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "svm_clf.classes_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "svm_clf.classes_[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5], dtype=uint8)"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.multiclass import OneVsRestClassifier\n",
    "ovr_clf = OneVsRestClassifier(SVC(gamma=\"auto\", random_state=42))\n",
    "ovr_clf.fit(X_train[:1000], y_train[:1000])\n",
    "ovr_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ovr_clf.estimators_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5], dtype=uint8)"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.fit(X_train, y_train)\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-15955.22627845, -38080.96296175, -13326.66694897,\n",
       "           573.52692379, -17680.6846644 ,   2412.53175101,\n",
       "        -25526.86498156, -12290.15704709,  -7946.05205023,\n",
       "        -10631.35888549]])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.decision_function([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.8489802 , 0.87129356, 0.86988048])"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.89707059, 0.8960948 , 0.90693604])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))\n",
    "cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5578,    0,   22,    7,    8,   45,   35,    5,  222,    1],\n",
       "       [   0, 6410,   35,   26,    4,   44,    4,    8,  198,   13],\n",
       "       [  28,   27, 5232,  100,   74,   27,   68,   37,  354,   11],\n",
       "       [  23,   18,  115, 5254,    2,  209,   26,   38,  373,   73],\n",
       "       [  11,   14,   45,   12, 5219,   11,   33,   26,  299,  172],\n",
       "       [  26,   16,   31,  173,   54, 4484,   76,   14,  482,   65],\n",
       "       [  31,   17,   45,    2,   42,   98, 5556,    3,  123,    1],\n",
       "       [  20,   10,   53,   27,   50,   13,    3, 5696,  173,  220],\n",
       "       [  17,   64,   47,   91,    3,  125,   24,   11, 5421,   48],\n",
       "       [  24,   18,   29,   67,  116,   39,    1,  174,  329, 5152]])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)\n",
    "conf_mx = confusion_matrix(y_train, y_train_pred)\n",
    "conf_mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "# since sklearn 0.22, you can use sklearn.metrics.plot_confusion_matrix()\n",
    "def plot_confusion_matrix(matrix):\n",
    "    \"\"\"If you prefer color and a colorbar\"\"\"\n",
    "    fig = plt.figure(figsize=(8,8))\n",
    "    ax = fig.add_subplot(111)\n",
    "    cax = ax.matshow(matrix)\n",
    "    fig.colorbar(cax)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure confusion_matrix_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.matshow(conf_mx, cmap=plt.cm.gray)\n",
    "save_fig(\"confusion_matrix_plot\", tight_layout=False)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "row_sums = conf_mx.sum(axis=1, keepdims=True)\n",
    "norm_conf_mx = conf_mx / row_sums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure confusion_matrix_errors_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "np.fill_diagonal(norm_conf_mx, 0)\n",
    "plt.matshow(norm_conf_mx, cmap=plt.cm.gray)\n",
    "save_fig(\"confusion_matrix_errors_plot\", tight_layout=False)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure error_analysis_digits_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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efJkIDnPG6n7U6ZM4c477wRgx44dAOTL598PHzp0iO+//z4xA4whOs937dqV4JF4/PvvvwBs27aNTz75BIBly5YB8MMPPwBwyimn0LBhQwAaNGiQgFFGl82bNwO462zNmjWAf6464ogjovIapuwYhmEYhpHSpKSyo9VvvXr1XGxdBCog7733HgArV64EPA/CeeedF49hhmXjxo2At2r/5ZdfMlVvwrFz5073eUgJKliwYJRGCWvXrgVgyZIlAFStWpVff/3VvTZ46lTfvn1z/HpSp+rWrQtA2bJlc/w3M6NHjx4sXrwYwP2Uh6V+/foUKlQI8LwAF1xwAQBnnXVWzMaUVfQdzJgxg3feeQfwPAz//PMPQJbPq7///htIfWVn1qxZAIwePZry5cune6xcuXIA3HTTTRmeJ5/L6NGjmT17NuApO/KGJAP6HqVefv/99zz88MMAVK5cGfCu727dunHppZcmYJQ5R9flyy+/DEC7du0SOZwM7Nu3D4B3330XgIEDBwLwxRdfONUt1DX6+uuvA/7rEKBGjRoxH2sodG5Pnz6dN954I8vPX7p0Ka1atQI8Ree+++4DPGUxGpiyYxiGYRhGSpNSys6UKVMAL+7366+/Orf9rbfeCvjVHvDHRe+++24ANm3aBMBzzz0HwKuvvhq3MWeG4rbr1693v9Nuq0OHDpk+TzFoeZQAF/dduHAhEDorIavI4zFz5kwAunfvDsCZZ57p4q/BcfDsKFPByFMghSeWu7QzzzyTo446CvB2X8pWUUYceDus/Pn9l1OVKlU455xzAE8JSlRGnM7tUFlVoly5clStWjXd76RktG3blnvuuQfwdpB5BXn5spp9JC/U6NGjqVixIgBXXHFFVMcWDSZNmgTA1q1bAX9Wp7LwpP698MILADzwwAMJUw5yiq5hqc+JZNu2bYA/AxKgevXq9OvXD4AVK1ZkOF4eLyn8v/32G+D3sugeod8lig8++ADAzXmZoblz6dKlgBdZGTBggFOwXnzxRQD+97//AdG5Z4iUWuxoYaCfxYsXd6mioSabadOmATBhwoT4DDAL6GYjiRCgadOmh33eunXrgPSLnVig8IgWOUIhs6yikNA555zDZ599dtjjteCL5WJn0KBB7kanBXDt2rXd4wpRzJkzB/AWdytWrHATl6RphQOOP/74mI03FApZXn311Rke6927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xBg4cCDXXXddwsYFKd4ba8mSJQwbNsz9P8D3338PQOXKlWnRogXgP+GSDV283377LYC7IAB3k01Ly7zVkI554okn3MVzyimnxGSsWWHjxo0ANG/eHIDly5cDsG/fvsM+t2jRopx88smAtziKJp9//jkAL7zwAgCffPIJW7ZsAeDAgQMZjtdnXLJkSQCefvppANq2bRv1saUI1hsrydFG46233gJg165dAKxbt44///wTgF9++SXdc5o0acKVV14JwN133x2XcWqxcOuttwLeuH0+H5deeikARx11FAAffvghAPv37wfg7bff5oYbbojLODPj999/B6BUqVKZHtOsWTMef/xxwFuoJSOauzt16sSkSZMA2LNnT7pjbrzxRndOxRjrjWUYhmEYRt4kpZQdreA7deoE+HcgWs2HQspI48aNAZg2bVp2XjbHfP755+nUBCAiRSESZSctLc39bSk8iWLjxo00a9YMgC+++CLdY0cccQQA119/PevXrwfg66+/zvA3JIuOGjUK8CTqnDBr1qx0f2vbtm2A/zMM/ozLli0L+M+t4O+hSJEigH9XrJ1ubuCVV17JIP1HylVXXQVArVq1Ijk85ZSdP/74g19//RXw1MZnnnkGgLVr1zqVoUmTJgDce++90XjZqHDw4EHAC9EOGjSIv//+G4CLL74Y8MZdtGhRzjjjDABq1KiR7u888sgjzJ8/H4DVq1fHfuDgQiJz5swB4PTTTwegdevWTg0RkydPBnBKfp8+fXj44YfjMs7M2L17N+D/fKVuC6lp+/bt49RTTwXgwQcfBLx725FHHhmvoR6WJ554AvCHEDU/SuWWBaF8+fJ89tlnQMzHbsqOYRiGYRh5k5RQdqZPnw54O3PtTho1asQjjzwCeDuOunXrArBw4UJuvvlmAAoUKABE5huJBlIOtOqdN29eOjUBMqo2FSpU4IQTTkh3jHYwH3/8MZdffjkA7dq1AzxvTFpamtt1L1iwIDZvKEJatWrFxIkT0/2ufPnygPfdde/e3cWzf/jhB8DbzaxevZpixYoBnuqjnU9O0OcTrDadeuqp7jMuWrQoAOeccw4AK1eu5NNPPwXgxRdfBDwVrl69erzxxhsAFC5cOMfjixZr1qwB4JprrgE89XD//v1kdx6QL0I7+8MoPCmj7Oi7f+CBB1i6dCngXbP6LM8++2w37+ixli1b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nTsUQ8k2wY5lzZo1ALz22mvpPveLL74AvG7FkWbs2LEAHDhwwN329ttvA9C+fftU/y9YsCAA9evXj+Qwk47169cDMGvWLFq0aAF4HbvVwTsYNWrUAODzzz/njDPOyMxbJlW7iAMHDrB69WoAPv74YwC++uord9+NN94IwMsvvwyQ2c/SSALWrl0LwE033ZTi/wBjxowBoHHjxpEfWOxi7SIMwzAMw0hOElLZmTx5MgDNmjVj3759vhcMouykx3333QfAG2+8ARC1+Pp1110HwLJly7J8LFJKvv32WwAqVKgQ6mGm4OjRowC88847ADz11FMAHDp0KEPPP/XUUwHczvett94CoESJEiEdZ7Jx+PBhAPr16wd4asO6deuoXbs2ADNnzgRgz549J3y9+vXrM2zYMADOPPPMjAwhqZQd8M759957D4Cnn34agOHDh/Poo48CsHjxYgCKFSsWiSGl4q+//gJ8Ct/06dMBnNdIajLAhRdeCPj8RuBT9sSvv/4KQKlSpcI+3mDs3bsX8KnIv/32G+Ap37///jsAK1euBHyqWt68eQHIlSsXALfeeivgU5iLFCkSuYGnwx9//EGtWrWAlIqOkLJz1113RXRcMU6ac0xCGpR3794N4BYHwciRIwd33303ABdffDEAr776KgBHjhzhgw8+AOCkk3zi19ChQ8M23vTQJBLsWHShdujQwU1Ay5cvB7wFwu7du9m1a1eK28J9LP379wegW7duWXq+Jq6pU6cCuBDLnDlzQjC65GXAgAEAvPDCC6nu0wK4UaNGQMrFzh9//AHAwIEDUzzniy++YMKECQAu7GukRCGq559/PsXtjzzyCK1btwait8gZMWIEAF27dgVg69at7r5ChQoBuB/+HDlysHPnTsALS59yyimAb/6MVghu/PjxADzxxBOAb+GmsVSqVAmAMmXKpPjrj475s88+A6B69eq0a9cuvIPOIB988EHQRU6soM9Ov5v//PMP+/fvB+CCCy4AoG3btkBsbFQtjGUYhmEYRkKTkMpOehQvXhzw7UR79uyZ4r4lS5YAMGXKFHfbwoULIze4dChatCj3339/itskK7dp0ybV4x966CEALrroIndbpI5FikwwFCaRKiX69u0L+NSbHTt2hG9wScx33313wscofOvP5s2bAZg3b16Kv0WKFOGSSy4J3QAThFWrVgHw0ksv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mgT4ishKMc9sD7cgmLJjGIZhGEZyYsqOYRiRwpQdwzDCiSk7hmEYhmEkJ7bYMQzDMAwjobHFjmEYhmEYCY0tdgzDMAzDSGhssWMYhmEYRkJjix3DMAzDMBIaW+wYhmEYhpHQxF3Xc8MwQsuRI0d49913AdiyZUuK+zp16hSWTu2GYRiRxJQdwzAMwzASmoSsoDxy5EgA7r33XgYMGABAsWLFgJD03ogZtm/fDviOt1evXgDs2LEjxWNq1KjB5MmTAciXL19kB2jENKtWrQKgevXqbN68OehjypUrxzfffAMQCoXHKigbYWXnzp3ccccdAOi3rVGjRgA0aNAAgAsuuCA6gzOyxH///QfA0aNHAciTJ096D7cKyoZhGIZhJCcJpex8//33ADRs2BCA3bt3u/tOOeUUAHr06AHAxo0badOmDQBly5bN+kgjyKJFiwB4/fXXAfjhhx8AWLdunXuMju/aa68FoEqVKpx++ulhH9tXX32V4m8wtm/fzv79+wEoXrz4CV9z8eLFANx///2AT6mLNtu2bQNgw4YNrFy5EoBx48YBMGHCBMC3o8yRw7fBuP322wHvO4ulXeXXX38NQO3atd010Lp16xSP6d+/P4ULFwZg+vTpAO7/WcCUHSMs6Lq87777mDZtGuApO7oWzz33XMCncFepUgWARx55BICKFStGdLyGx759+zh27BgAb7zxBgB79uxx9//4448AzJw5E/C+1zT8pW3IAAAgAElEQVQwZccwDMMwjOQkoZQdeVOk7AAULFgQwCkKR44c8b3B8eOcddZZgOfxuemmm7I43PCzevVqrr76agD27t0LeCvc8847j6eeegqARx99FICTTorMOlYeIe2M/FWmjBC4+wpG06ZNARg9enQWRhgapN48+eSTAKxfv96NOfAY/JUd3Ve0aFEAZsyYQenSpSM38HTwV3bkc9BxihUrVtC/f38Azj//fACef/75rL6lKTtGSNm5cycA99xzD4BTdSD9uUX36TdAvx2aY43wcfjwYQDmz58P+H6vA72m6ZFVZSehUs81efujH98333wTgOeee87dt3XrVsBbHE2ZMgWAatWqhXOYmUInRvPmzd0iR9SrVw+AV155JWo/oB999BHgfc558+bllltuAWDixIkAlC9fHoADBw7w22+/nfA1W7VqBUDOnL7TU+HGWOCff/4BUl5w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vvnmbL3m4sWLAV/LjGuuuQYI3tYpk5iyYxiGYRhGchLb2+MQoGJM2pXI01KoUKFUj5UXZsiQIS5rSKtPxX21Ao0lTjnlFO6//37A221HqibNb7/9BkDDhg0BXyaKVv4nnZT5tXTx4sVdRpkKhW3YsAHwZbdImVMRwlhFJd8DPQAxqqSmyY4dO6I9hJhHBRhffvllwPPLffvtt07xkJIQKeQfksIbitpOqr0kP6Pmxqxc5yfiyiuvpFu3boBXV0xet+zy888/uwa/yrqNJa+OOOmkk1xLF80bUg0XL17MQw89BMBTTz0FhFcpVmPXU089NduKjpDPFDxfZjhJ+MWOyIhRV2bmrl27provllITg3Httdem+L8monCj7sFaTLZu3dr1XpL0Gkq0II110qrcXahQoewU5YsYCxYsAIL3KovFsgaxgMpa9OjRA4Dp06e79GylRnfo0AEIzwLBH3X+VgXwbt26uVIDWUXm9cBQTzjKc9SqVctVR9a1VLlyZcD3+WaluN706dMB3/yuop/qpB1LJUb80XnSunVrwNtENW/e3JUg0YbklVdeAbyqxaFEG85KlSq5Cs/XXXddll5LwoF/kcrHH388myM8MRbGMgzDMAwjoUkaZScjqNCUDKT++BchjEUC20REs/9Lp06dAChRogQANWrUyPBzH3vsMReKC1RFwOteHw60Q1JRr+x856tWrQK8DuOifPny2TZxh4M9e/YAXnruq6++CsDevXvdY+6++24A1z7CCI46m997773OYKprQmbbcCsJ7du3B7xyFS1btuS+++4D4NFHHwUyf36rzYjKKohg6l92Oeecc1zBQLX8USJJo0aNXBhbx6lwVDAUSpTi5t+nqV27dqjTq+YAACAASURBVKEdeCaZO3euK+p51VVXAenP3SrWt3nzZtd3T5+L1K6vv/6aihUrhmW8H330kfs8leAjq4isFMFYtWqVSzlXOQOpa9WqVQtlu4g0MWXHMAzDMIyEJm5Sz9WAUb6arVu3AlC4cGH+/vvvFI+VufiOO+5I9020IlZ8W2Wsjx075h4zYMAAwIspptfWIJpolT948GAgckUFlZIv05q/EiBjYXrKzvfffw94je4WL17sOm8HUqhQIWdqC0fDU3kDpGD07dvX7aQyY/g+duyYa+b3xRdfAN55s3bt2oiY8TLDokWL3A553rx5qe7X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sGHDnIKonY3qpMKZkwYvj68RIR06dAB8XSqpqalA7junZFQo1Uifm5SUlISs2RH6nJQvX55evXoBXr2S6uzOP/98V/un91q1cDpu/dExMmvWLBYvXgx4r69o2rSpOzfEA/6KVG7GTeQHjUVp37494Ck7GqAMnoVA586dATh06FCm51FrvwaCRppVq1a5169q1aoAtGzZMke/u23bNsBTGfW5DFTyQ41UYik1UnY2bdrkzj856SbU8R8ptT5uHZTXr18P+E4wepPVgitZLz093V24NE8q2NRztUuGO32VHZL2lO6QNCzPhOTkZNcynpMTig627777zhWpyrdm9OjRAO4EnheUClOhuAKFZs2auaAxO3bu3Al4H1QV1O7cudMVKAsVFmqSe6iRfDxmzBjA81dp0aKF+z4YmzZtArxAWifcQ4cOuRkvEyZMAMKTnswOBVu6EG/evNm15ep4UGAdbIL8vn37AN9xpMJHtYrKkbtDhw4cc0yuxOFYMnbK1YlPmyallyThy03WHxVp1qlTh1WrVmW4T8e9P0ptyiure/fuIfdiyg6da/r06eOCsZygi1XDhg1d+kK3hRt99hRs6xju27evuw7IX0yfS390wdYMu0jMkgvGm2++6c4VKvxVkFaqVCk32Tzwdd2wYQM9evQAvM+qrg+LFi0Kq8t0VqSnp7vzndbkzxVXXAF465SNQ4jbzc1B2TAMwzCMgkncKjuicePGziAqcHp5sMnmip579uxJSkpK6FYcIiRpa5enabDgRcI5KYiUy63/+6s00FNPPQVAsWLF8rxOzXpq0qRJhtt/+uknypUrl+E27Ureeecd127/008/AcGL6bSuBx54APBagcO129VuVjss7RILFSqUq2JuSeIDBw50Jln5eY1DwQ8//AD4VKsFCxYAXipGCmH58uUzfXakXKxbt861tqrAMx9uuXGr7ASi13XEiBF8+eWXgGeVIBXZ//wj9BmuWbOm2+FKPTz22GPzs6R8U7FiRafQSO0MpiLr86wU0tatW8M6EysYeq1vueUWwDO6zAmNGjVyjr2BTueRZvHixU7xkBqiY6ZUqVJu/pRm3QVTQXTcSFGPZoYiBjBlxzAMwzCMgkncKztbtmxxeULtRpWH9d9ZaZKt6nmCzciKJVQLoBbmJUuWuFyuVJWc0Lx5cxfpS7mQCV1+UC2Uiv9CRevW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\n",
      "text/plain": [
       "<Figure size 576x576 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "cl_a, cl_b = 3, 5\n",
    "X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]\n",
    "X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]\n",
    "X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]\n",
    "X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]\n",
    "\n",
    "plt.figure(figsize=(8,8))\n",
    "plt.subplot(221); plot_digits(X_aa[:25], images_per_row=5)\n",
    "plt.subplot(222); plot_digits(X_ab[:25], images_per_row=5)\n",
    "plt.subplot(223); plot_digits(X_ba[:25], images_per_row=5)\n",
    "plt.subplot(224); plot_digits(X_bb[:25], images_per_row=5)\n",
    "save_fig(\"error_analysis_digits_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multilabel classification"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "y_train_large = (y_train >= 7)\n",
    "y_train_odd = (y_train % 2 == 1)\n",
    "y_multilabel = np.c_[y_train_large, y_train_odd]\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train, y_multilabel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True]])"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Warning**: the following cell may take a very long time (possibly hours depending on your hardware)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.976410265560605"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)\n",
    "f1_score(y_multilabel, y_train_knn_pred, average=\"macro\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multioutput classification"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "noise = np.random.randint(0, 100, (len(X_train), 784))\n",
    "X_train_mod = X_train + noise\n",
    "noise = np.random.randint(0, 100, (len(X_test), 784))\n",
    "X_test_mod = X_test + noise\n",
    "y_train_mod = X_train\n",
    "y_test_mod = X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure noisy_digit_example_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "some_index = 0\n",
    "plt.subplot(121); plot_digit(X_test_mod[some_index])\n",
    "plt.subplot(122); plot_digit(y_test_mod[some_index])\n",
    "save_fig(\"noisy_digit_example_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving figure cleaned_digit_example_plot\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "knn_clf.fit(X_train_mod, y_train_mod)\n",
    "clean_digit = knn_clf.predict([X_test_mod[some_index]])\n",
    "plot_digit(clean_digit)\n",
    "save_fig(\"cleaned_digit_example_plot\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extra material"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dummy (ie. random) classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.dummy import DummyClassifier\n",
    "dmy_clf = DummyClassifier()\n",
    "y_probas_dmy = cross_val_predict(dmy_clf, X_train, y_train_5, cv=3, method=\"predict_proba\")\n",
    "y_scores_dmy = y_probas_dmy[:, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fprr, tprr, thresholdsr = roc_curve(y_train_5, y_scores_dmy)\n",
    "plot_roc_curve(fprr, tprr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## KNN classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=None, n_neighbors=4, p=2,\n",
       "           weights='distance')"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "knn_clf = KNeighborsClassifier(weights='distance', n_neighbors=4)\n",
    "knn_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_knn_pred = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9714"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "accuracy_score(y_test, y_knn_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP0AAAD8CAYAAAC8aaJZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAABu5JREFUeJzt3UuIzf8fx/Ez7kyu2SBZsBK5RLNQwoKV206JqJGFy8akZGNh9bNjlJiFLCjJLGYlioWUJBJlkkIWbMQCRZr/9r9w3uM3xpzxez0ey3n1nfNNPfssPs3RNjAw0AByjGn1CwAjS/QQRvQQRvQQRvQQRvQQZlwrPrSnp8c9IfxhnZ2dbT/7uZMewogewogewogewogewogewogewrTknn406+zsbPUrwB/lpIcwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocwoocw41r9AvDjx49y//Tp0x/77O7u7nL/8uVLuff395f72bNny72rq6vpduXKlfLZSZMmlfvXr19/+nMnPYQRPYQRPYQRPYQRPYQRPYRxZUej0Wg03rx5U+7fvn0r93v37pX73bt3m24fP34sn7127Vq5t9L8+fPL/dChQ+Xe29vbdJs6dWr57LJly8q9GSc9hBE9hBE9hBE9hBE9hBE9hBE9hHFPH+LRo0flvmHDhnL/k3/eOpqNHTu23E+ePFnu7e3t5b5z586m29y5c8tnZ86cWe7NOOkhjOghjOghjOghjOghjOghjOghjHv6EAsWLCj32bNnl/tovqfv6Ogo9+o++/bt2+WzEyZMKPddu3aV+2jkpIcwoocwoocwoocwoocwoocwoocw7ulDzJo1q9xPnTpV7n19feW+YsWKcj98+HC5V5YvX17ut27dKvfqb9qfPn1aPnv69Oly/xs56SGM6CGM6CGM6CGM6CGM6CGM6CGMe3oajUajsW3btnIf7HvxB/u/1J88edJ06+npKZ/t6uoq98G+W76yZMmScj9//vyQf/do5aSHMKKHMKKHMKKHMKKHMKKHMK7s+CXTpk37reenT58+5GcHu9LbsWNHuY8Z42z7f/41IIzoIYzoIYzoIYzoIYzoIYzoIYx7ekbEiRMnmm4PHz4sn71z5065D/YV2Bs3biz3NE56CCN6CCN6CCN6CCN6CCN6CCN6COOenhFRfU31hQsXymdXrlxZ7vv27Sv39evXN91WrVpVPnvgwIFyb2trK/fRyEkPYUQPYUQPYUQPYUQPYUQPYUQPYdzT03ILFy4s94sXL5b73r17y/3SpUtD2hqNRuPz58/lvnv37nKfM2dOubeCkx7CiB7CiB7CiB7CiB7CiB7CiB7CuKdn1Nu+fXu5L1q0qNyPHDnSdBvsO/OPHTtW7q9fvy7348ePl/u8efPK/U9w0kMY0UMY0UMY0UMY0UMY0UMYV3b89ZYuXVruV69ebbr19fWVz+7Zs6fcz507V+4vXrwo95s3b5b7n+CkhzCihzCihzCihzCihzCihzCihzBtAwMDI/6hPT09I/+hv6izs7PVr8AoMnHixHL//v17uY8fP77cb9y40XRbt25d+ewv+On/o+2khzCihzCihzCihzCihzCihzCihzD+np6/3pMnT8r92rVrTbcHDx6Uzw52Dz+YxYsXl/vatWt/6/cPhZMewogewogewogewogewogewogewrinp+X6+/vL/cyZM+V+/fr1cn/37t2/fqdfNW5cndCcOXPKfcyYkT93nfQQRvQQRvQQRvQQRvQQRvQQxpUdw2Kwa7HLly833bq7u8tnX716NZRXGharV68u9+PHj5f7li1bhvN1hoWTHsKIHsKIHsKIHsKIHsKIHsKIHsK4p6fRaDQa79+/L/dnz56V+8GDB8v9+fPn//qdhktHR0fT7ejRo+WzW7duLfdW/Gns7/r73hj4LaKHMKKHMKKHMKKHMKKHMKKHMO7p/0M+fPjQdNu/f3/57OPHj8v95cuXQ3qn4bBmzZpyP3LkSLlv2rSp6TZ58uQhvdPfzEkPYUQPYUQPYUQPYUQPYUQPYUQPYdzTjyL3798v93/++afcHzx40HR7+/btkN5puEyZMqXpdvjw4fLZwb5bvr29fUjvlMpJD2FED2FED2FED2FED2FED2FED2Hc048ivb29v7X/jsWLF5f75s2by33s2LHl3tXV1XSbMWNG+SzDy0kPYUQPYUQPYUQPYUQPYUQPYdoGBgZG/EN7enpG/kN/UWdnZ6tfAYZL289+6KSHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMKKHMC35e3qgdZz0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EEb0EOZ//SLyMUPkY7wAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.ndimage.interpolation import shift\n",
    "def shift_digit(digit_array, dx, dy, new=0):\n",
    "    return shift(digit_array.reshape(28, 28), [dy, dx], cval=new).reshape(784)\n",
    "\n",
    "plot_digit(shift_digit(some_digit, 5, 1, new=100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((300000, 784), (300000,))"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_expanded = [X_train]\n",
    "y_train_expanded = [y_train]\n",
    "for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):\n",
    "    shifted_images = np.apply_along_axis(shift_digit, axis=1, arr=X_train, dx=dx, dy=dy)\n",
    "    X_train_expanded.append(shifted_images)\n",
    "    y_train_expanded.append(y_train)\n",
    "\n",
    "X_train_expanded = np.concatenate(X_train_expanded)\n",
    "y_train_expanded = np.concatenate(y_train_expanded)\n",
    "X_train_expanded.shape, y_train_expanded.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=None, n_neighbors=4, p=2,\n",
       "           weights='distance')"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.fit(X_train_expanded, y_train_expanded)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_knn_expanded_pred = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9763"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "accuracy_score(y_test, y_knn_expanded_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.24579675, 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.75420325]])"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ambiguous_digit = X_test[2589]\n",
    "knn_clf.predict_proba([ambiguous_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_digit(ambiguous_digit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise solutions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. An MNIST Classifier With Over 97% Accuracy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Warning**: the next cell may take hours to run, depending on your hardware."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
      "[CV] n_neighbors=3, weights=uniform ..................................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  n_neighbors=3, weights=uniform, score=0.9717617659308622, total=10.9min\n",
      "[CV] n_neighbors=3, weights=uniform ..................................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed: 52.2min remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  n_neighbors=3, weights=uniform, score=0.9706715547408765, total=10.7min\n",
      "[CV] n_neighbors=3, weights=uniform ..................................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   2 out of   2 | elapsed: 103.2min remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  n_neighbors=3, weights=uniform, score=0.9689166666666666, total=10.1min\n",
      "[CV] n_neighbors=3, weights=uniform ..................................\n",
      "[CV]  n_neighbors=3, weights=uniform, score=0.968575477202634, total=11.0min\n",
      "[CV] n_neighbors=3, weights=uniform ..................................\n",
      "[CV]  n_neighbors=3, weights=uniform, score=0.9704068022674225, total=11.0min\n",
      "[CV] n_neighbors=3, weights=distance .................................\n",
      "[CV]  n_neighbors=3, weights=distance, score=0.9723448563098709, total=10.9min\n",
      "[CV] n_neighbors=3, weights=distance .................................\n",
      "[CV]  n_neighbors=3, weights=distance, score=0.9716713881019831, total=11.2min\n",
      "[CV] n_neighbors=3, weights=distance .................................\n",
      "[CV]  n_neighbors=3, weights=distance, score=0.9700833333333333, total= 9.9min\n",
      "[CV] n_neighbors=3, weights=distance .................................\n",
      "[CV]  n_neighbors=3, weights=distance, score=0.9700758522964075, total=10.0min\n",
      "[CV] n_neighbors=3, weights=distance .................................\n",
      "[CV]  n_neighbors=3, weights=distance, score=0.971407135711904, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9690129112869638, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9682552907848692, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9675833333333334, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9673251646244895, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.970323441147049, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9730112453144523, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9722546242292951, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9699166666666666, total= 9.9min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9709093940151705, total=10.5min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9719906635545181, total=10.7min\n",
      "[CV] n_neighbors=5, weights=uniform ..................................\n",
      "[CV]  n_neighbors=5, weights=uniform, score=0.9697625989171179, total=10.9min\n",
      "[CV] n_neighbors=5, weights=uniform ..................................\n",
      "[CV]  n_neighbors=5, weights=uniform, score=0.9701716380603232, total=10.5min\n",
      "[CV] n_neighbors=5, weights=uniform ..................................\n",
      "[CV]  n_neighbors=5, weights=uniform, score=0.9694166666666667, total=10.5min\n",
      "[CV] n_neighbors=5, weights=uniform ..................................\n",
      "[CV]  n_neighbors=5, weights=uniform, score=0.9681587063432525, total=10.7min\n",
      "[CV] n_neighbors=5, weights=uniform ..................................\n",
      "[CV]  n_neighbors=5, weights=uniform, score=0.9689896632210737, total=10.6min\n",
      "[CV] n_neighbors=5, weights=distance .................................\n",
      "[CV]  n_neighbors=5, weights=distance, score=0.9703456892961266, total=10.6min\n",
      "[CV] n_neighbors=5, weights=distance .................................\n",
      "[CV]  n_neighbors=5, weights=distance, score=0.9713381103149475, total=11.1min\n",
      "[CV] n_neighbors=5, weights=distance .................................\n",
      "[CV]  n_neighbors=5, weights=distance, score=0.9704166666666667, total=10.4min\n",
      "[CV] n_neighbors=5, weights=distance .................................\n",
      "[CV]  n_neighbors=5, weights=distance, score=0.969409018921397, total=10.6min\n",
      "[CV] n_neighbors=5, weights=distance .................................\n",
      "[CV]  n_neighbors=5, weights=distance, score=0.9706568856285428, total=12.7min\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done  30 out of  30 | elapsed: 1523.6min finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "       estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "           weights='uniform'),\n",
       "       fit_params=None, iid='warn', n_jobs=None,\n",
       "       param_grid=[{'weights': ['uniform', 'distance'], 'n_neighbors': [3, 4, 5]}],\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring=None, verbose=3)"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "param_grid = [{'weights': [\"uniform\", \"distance\"], 'n_neighbors': [3, 4, 5]}]\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "grid_search = GridSearchCV(knn_clf, param_grid, cv=5, verbose=3)\n",
    "grid_search.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'n_neighbors': 4, 'weights': 'distance'}"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid_search.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9716166666666667"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid_search.best_score_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9714"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "y_pred = grid_search.predict(X_test)\n",
    "accuracy_score(y_test, y_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Data Augmentation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.ndimage.interpolation import shift"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shift_image(image, dx, dy):\n",
    "    image = image.reshape((28, 28))\n",
    "    shifted_image = shift(image, [dy, dx], cval=0, mode=\"constant\")\n",
    "    return shifted_image.reshape([-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x216 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "image = X_train[1000]\n",
    "shifted_image_down = shift_image(image, 0, 5)\n",
    "shifted_image_left = shift_image(image, -5, 0)\n",
    "\n",
    "plt.figure(figsize=(12,3))\n",
    "plt.subplot(131)\n",
    "plt.title(\"Original\", fontsize=14)\n",
    "plt.imshow(image.reshape(28, 28), interpolation=\"nearest\", cmap=\"Greys\")\n",
    "plt.subplot(132)\n",
    "plt.title(\"Shifted down\", fontsize=14)\n",
    "plt.imshow(shifted_image_down.reshape(28, 28), interpolation=\"nearest\", cmap=\"Greys\")\n",
    "plt.subplot(133)\n",
    "plt.title(\"Shifted left\", fontsize=14)\n",
    "plt.imshow(shifted_image_left.reshape(28, 28), interpolation=\"nearest\", cmap=\"Greys\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train_augmented = [image for image in X_train]\n",
    "y_train_augmented = [label for label in y_train]\n",
    "\n",
    "for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):\n",
    "    for image, label in zip(X_train, y_train):\n",
    "        X_train_augmented.append(shift_image(image, dx, dy))\n",
    "        y_train_augmented.append(label)\n",
    "\n",
    "X_train_augmented = np.array(X_train_augmented)\n",
    "y_train_augmented = np.array(y_train_augmented)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "shuffle_idx = np.random.permutation(len(X_train_augmented))\n",
    "X_train_augmented = X_train_augmented[shuffle_idx]\n",
    "y_train_augmented = y_train_augmented[shuffle_idx]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_clf = KNeighborsClassifier(**grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=None, n_neighbors=4, p=2,\n",
       "           weights='distance')"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.fit(X_train_augmented, y_train_augmented)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9763"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_pred = knn_clf.predict(X_test)\n",
    "accuracy_score(y_test, y_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By simply augmenting the data, we got a 0.5% accuracy boost. :)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Tackle the Titanic dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The goal is to predict whether or not a passenger survived based on attributes such as their age, sex, passenger class, where they embarked and so on."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, login to [Kaggle](https://www.kaggle.com/) and go to the [Titanic challenge](https://www.kaggle.com/c/titanic) to download `train.csv` and `test.csv`. Save them to the `datasets/titanic` directory."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, let's load the data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "TITANIC_PATH = os.path.join(\"datasets\", \"titanic\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "def load_titanic_data(filename, titanic_path=TITANIC_PATH):\n",
    "    csv_path = os.path.join(titanic_path, filename)\n",
    "    return pd.read_csv(csv_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data = load_titanic_data(\"train.csv\")\n",
    "test_data = load_titanic_data(\"test.csv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The data is already split into a training set and a test set. However, the test data does *not* contain the labels: your goal is to train the best model you can using the training data, then make your predictions on the test data and upload them to Kaggle to see your final score."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a peek at the top few rows of the training set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PassengerId</th>\n",
       "      <th>Survived</th>\n",
       "      <th>Pclass</th>\n",
       "      <th>Name</th>\n",
       "      <th>Sex</th>\n",
       "      <th>Age</th>\n",
       "      <th>SibSp</th>\n",
       "      <th>Parch</th>\n",
       "      <th>Ticket</th>\n",
       "      <th>Fare</th>\n",
       "      <th>Cabin</th>\n",
       "      <th>Embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>Braund, Mr. Owen Harris</td>\n",
       "      <td>male</td>\n",
       "      <td>22.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>A/5 21171</td>\n",
       "      <td>7.2500</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Cumings, Mrs. John Bradley (Florence Briggs Th...</td>\n",
       "      <td>female</td>\n",
       "      <td>38.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>PC 17599</td>\n",
       "      <td>71.2833</td>\n",
       "      <td>C85</td>\n",
       "      <td>C</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>Heikkinen, Miss. Laina</td>\n",
       "      <td>female</td>\n",
       "      <td>26.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>STON/O2. 3101282</td>\n",
       "      <td>7.9250</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Futrelle, Mrs. Jacques Heath (Lily May Peel)</td>\n",
       "      <td>female</td>\n",
       "      <td>35.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>113803</td>\n",
       "      <td>53.1000</td>\n",
       "      <td>C123</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>Allen, Mr. William Henry</td>\n",
       "      <td>male</td>\n",
       "      <td>35.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>373450</td>\n",
       "      <td>8.0500</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   PassengerId  Survived  Pclass  \\\n",
       "0            1         0       3   \n",
       "1            2         1       1   \n",
       "2            3         1       3   \n",
       "3            4         1       1   \n",
       "4            5         0       3   \n",
       "\n",
       "                                                Name     Sex   Age  SibSp  \\\n",
       "0                            Braund, Mr. Owen Harris    male  22.0      1   \n",
       "1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   \n",
       "2                             Heikkinen, Miss. Laina  female  26.0      0   \n",
       "3       Futrelle, Mrs. Jacques Heath (Lily May Peel)  female  35.0      1   \n",
       "4                           Allen, Mr. William Henry    male  35.0      0   \n",
       "\n",
       "   Parch            Ticket     Fare Cabin Embarked  \n",
       "0      0         A/5 21171   7.2500   NaN        S  \n",
       "1      0          PC 17599  71.2833   C85        C  \n",
       "2      0  STON/O2. 3101282   7.9250   NaN        S  \n",
       "3      0            113803  53.1000  C123        S  \n",
       "4      0            373450   8.0500   NaN        S  "
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The attributes have the following meaning:\n",
    "* **Survived**: that's the target, 0 means the passenger did not survive, while 1 means he/she survived.\n",
    "* **Pclass**: passenger class.\n",
    "* **Name**, **Sex**, **Age**: self-explanatory\n",
    "* **SibSp**: how many siblings & spouses of the passenger aboard the Titanic.\n",
    "* **Parch**: how many children & parents of the passenger aboard the Titanic.\n",
    "* **Ticket**: ticket id\n",
    "* **Fare**: price paid (in pounds)\n",
    "* **Cabin**: passenger's cabin number\n",
    "* **Embarked**: where the passenger embarked the Titanic"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's get more info to see how much data is missing:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 891 entries, 0 to 890\n",
      "Data columns (total 12 columns):\n",
      "PassengerId    891 non-null int64\n",
      "Survived       891 non-null int64\n",
      "Pclass         891 non-null int64\n",
      "Name           891 non-null object\n",
      "Sex            891 non-null object\n",
      "Age            714 non-null float64\n",
      "SibSp          891 non-null int64\n",
      "Parch          891 non-null int64\n",
      "Ticket         891 non-null object\n",
      "Fare           891 non-null float64\n",
      "Cabin          204 non-null object\n",
      "Embarked       889 non-null object\n",
      "dtypes: float64(2), int64(5), object(5)\n",
      "memory usage: 83.6+ KB\n"
     ]
    }
   ],
   "source": [
    "train_data.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, the **Age**, **Cabin** and **Embarked** attributes are sometimes null (less than 891 non-null), especially the **Cabin** (77% are null). We will ignore the **Cabin** for now and focus on the rest. The **Age** attribute has about 19% null values, so we will need to decide what to do with them. Replacing null values with the median age seems reasonable."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The **Name** and **Ticket** attributes may have some value, but they will be a bit tricky to convert into useful numbers that a model can consume. So for now, we will ignore them."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the numerical attributes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PassengerId</th>\n",
       "      <th>Survived</th>\n",
       "      <th>Pclass</th>\n",
       "      <th>Age</th>\n",
       "      <th>SibSp</th>\n",
       "      <th>Parch</th>\n",
       "      <th>Fare</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>714.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>446.000000</td>\n",
       "      <td>0.383838</td>\n",
       "      <td>2.308642</td>\n",
       "      <td>29.699118</td>\n",
       "      <td>0.523008</td>\n",
       "      <td>0.381594</td>\n",
       "      <td>32.204208</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>257.353842</td>\n",
       "      <td>0.486592</td>\n",
       "      <td>0.836071</td>\n",
       "      <td>14.526497</td>\n",
       "      <td>1.102743</td>\n",
       "      <td>0.806057</td>\n",
       "      <td>49.693429</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.420000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>223.500000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>20.125000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>7.910400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>446.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>28.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>14.454200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>668.500000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>38.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>31.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>891.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>80.000000</td>\n",
       "      <td>8.000000</td>\n",
       "      <td>6.000000</td>\n",
       "      <td>512.329200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       PassengerId    Survived      Pclass         Age       SibSp  \\\n",
       "count   891.000000  891.000000  891.000000  714.000000  891.000000   \n",
       "mean    446.000000    0.383838    2.308642   29.699118    0.523008   \n",
       "std     257.353842    0.486592    0.836071   14.526497    1.102743   \n",
       "min       1.000000    0.000000    1.000000    0.420000    0.000000   \n",
       "25%     223.500000    0.000000    2.000000   20.125000    0.000000   \n",
       "50%     446.000000    0.000000    3.000000   28.000000    0.000000   \n",
       "75%     668.500000    1.000000    3.000000   38.000000    1.000000   \n",
       "max     891.000000    1.000000    3.000000   80.000000    8.000000   \n",
       "\n",
       "            Parch        Fare  \n",
       "count  891.000000  891.000000  \n",
       "mean     0.381594   32.204208  \n",
       "std      0.806057   49.693429  \n",
       "min      0.000000    0.000000  \n",
       "25%      0.000000    7.910400  \n",
       "50%      0.000000   14.454200  \n",
       "75%      0.000000   31.000000  \n",
       "max      6.000000  512.329200  "
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Yikes, only 38% **Survived**. :(  That's close enough to 40%, so accuracy will be a reasonable metric to evaluate our model.\n",
    "* The mean **Fare** was £32.20, which does not seem so expensive (but it was probably a lot of money back then).\n",
    "* The mean **Age** was less than 30 years old."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's check that the target is indeed 0 or 1:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    549\n",
       "1    342\n",
       "Name: Survived, dtype: int64"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data[\"Survived\"].value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's take a quick look at all the categorical attributes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3    491\n",
       "1    216\n",
       "2    184\n",
       "Name: Pclass, dtype: int64"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data[\"Pclass\"].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "male      577\n",
       "female    314\n",
       "Name: Sex, dtype: int64"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data[\"Sex\"].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "S    644\n",
       "C    168\n",
       "Q     77\n",
       "Name: Embarked, dtype: int64"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data[\"Embarked\"].value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Embarked attribute tells us where the passenger embarked: C=Cherbourg, Q=Queenstown, S=Southampton."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**: the code below uses a mix of `Pipeline`, `FeatureUnion` and a custom `DataFrameSelector` to preprocess some columns differently.  Since Scikit-Learn 0.20, it is preferable to use a `ColumnTransformer`, like in the previous chapter."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's build our preprocessing pipelines. We will reuse the `DataframeSelector` we built in the previous chapter to select specific attributes from the `DataFrame`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.base import BaseEstimator, TransformerMixin\n",
    "\n",
    "class DataFrameSelector(BaseEstimator, TransformerMixin):\n",
    "    def __init__(self, attribute_names):\n",
    "        self.attribute_names = attribute_names\n",
    "    def fit(self, X, y=None):\n",
    "        return self\n",
    "    def transform(self, X):\n",
    "        return X[self.attribute_names]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's build the pipeline for the numerical attributes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.impute import SimpleImputer\n",
    "\n",
    "num_pipeline = Pipeline([\n",
    "        (\"select_numeric\", DataFrameSelector([\"Age\", \"SibSp\", \"Parch\", \"Fare\"])),\n",
    "        (\"imputer\", SimpleImputer(strategy=\"median\")),\n",
    "    ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[22.    ,  1.    ,  0.    ,  7.25  ],\n",
       "       [38.    ,  1.    ,  0.    , 71.2833],\n",
       "       [26.    ,  0.    ,  0.    ,  7.925 ],\n",
       "       ...,\n",
       "       [28.    ,  1.    ,  2.    , 23.45  ],\n",
       "       [26.    ,  0.    ,  0.    , 30.    ],\n",
       "       [32.    ,  0.    ,  0.    ,  7.75  ]])"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_pipeline.fit_transform(train_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will also need an imputer for the string categorical columns (the regular `SimpleImputer` does not work on those):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Inspired from stackoverflow.com/questions/25239958\n",
    "class MostFrequentImputer(BaseEstimator, TransformerMixin):\n",
    "    def fit(self, X, y=None):\n",
    "        self.most_frequent_ = pd.Series([X[c].value_counts().index[0] for c in X],\n",
    "                                        index=X.columns)\n",
    "        return self\n",
    "    def transform(self, X, y=None):\n",
    "        return X.fillna(self.most_frequent_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import OneHotEncoder"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can build the pipeline for the categorical attributes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "cat_pipeline = Pipeline([\n",
    "        (\"select_cat\", DataFrameSelector([\"Pclass\", \"Sex\", \"Embarked\"])),\n",
    "        (\"imputer\", MostFrequentImputer()),\n",
    "        (\"cat_encoder\", OneHotEncoder(sparse=False)),\n",
    "    ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 1., ..., 0., 0., 1.],\n",
       "       [1., 0., 0., ..., 1., 0., 0.],\n",
       "       [0., 0., 1., ..., 0., 0., 1.],\n",
       "       ...,\n",
       "       [0., 0., 1., ..., 0., 0., 1.],\n",
       "       [1., 0., 0., ..., 1., 0., 0.],\n",
       "       [0., 0., 1., ..., 0., 1., 0.]])"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cat_pipeline.fit_transform(train_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, let's join the numerical and categorical pipelines:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.pipeline import FeatureUnion\n",
    "preprocess_pipeline = FeatureUnion(transformer_list=[\n",
    "        (\"num_pipeline\", num_pipeline),\n",
    "        (\"cat_pipeline\", cat_pipeline),\n",
    "    ])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cool! Now we have a nice preprocessing pipeline that takes the raw data and outputs numerical input features that we can feed to any Machine Learning model we want."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[22.,  1.,  0., ...,  0.,  0.,  1.],\n",
       "       [38.,  1.,  0., ...,  1.,  0.,  0.],\n",
       "       [26.,  0.,  0., ...,  0.,  0.,  1.],\n",
       "       ...,\n",
       "       [28.,  1.,  2., ...,  0.,  0.,  1.],\n",
       "       [26.,  0.,  0., ...,  1.,  0.,  0.],\n",
       "       [32.,  0.,  0., ...,  0.,  1.,  0.]])"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train = preprocess_pipeline.fit_transform(train_data)\n",
    "X_train"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's not forget to get the labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train = train_data[\"Survived\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are now ready to train a classifier. Let's start with an `SVC`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,\n",
       "  decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',\n",
       "  max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
       "  tol=0.001, verbose=False)"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.svm import SVC\n",
    "\n",
    "svm_clf = SVC(gamma=\"auto\")\n",
    "svm_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great, our model is trained, let's use it to make predictions on the test set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_test = preprocess_pipeline.transform(test_data)\n",
    "y_pred = svm_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And now we could just build a CSV file with these predictions (respecting the format excepted by Kaggle), then upload it and hope for the best. But wait! We can do better than hope. Why don't we use cross-validation to have an idea of how good our model is?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7365250822835092"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "svm_scores = cross_val_score(svm_clf, X_train, y_train, cv=10)\n",
    "svm_scores.mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, over 73% accuracy, clearly better than random chance, but it's not a great score. Looking at the [leaderboard](https://www.kaggle.com/c/titanic/leaderboard) for the Titanic competition on Kaggle, you can see that you need to reach above 80% accuracy to be within the top 10% Kagglers. Some reached 100%, but since you can easily find the [list of victims](https://www.encyclopedia-titanica.org/titanic-victims/) of the Titanic, it seems likely that there was little Machine Learning involved in their performance! ;-) So let's try to build a model that reaches 80% accuracy."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try a `RandomForestClassifier`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8149526160481217"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "\n",
    "forest_clf = RandomForestClassifier(n_estimators=100, random_state=42)\n",
    "forest_scores = cross_val_score(forest_clf, X_train, y_train, cv=10)\n",
    "forest_scores.mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That's much better!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Instead of just looking at the mean accuracy across the 10 cross-validation folds, let's plot all 10 scores for each model, along with a box plot highlighting the lower and upper quartiles, and \"whiskers\" showing the extent of the scores (thanks to Nevin Yilmaz for suggesting this visualization). Note that the `boxplot()` function detects outliers (called \"fliers\") and does not include them within the whiskers. Specifically, if the lower quartile is $Q_1$ and the upper quartile is $Q_3$, then the interquartile range $IQR = Q_3 - Q_1$ (this is the box's height), and any score lower than $Q_1 - 1.5 \\times IQR$ is a flier, and so is any score greater than $Q3 + 1.5 \\times IQR$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 4))\n",
    "plt.plot([1]*10, svm_scores, \".\")\n",
    "plt.plot([2]*10, forest_scores, \".\")\n",
    "plt.boxplot([svm_scores, forest_scores], labels=(\"SVM\",\"Random Forest\"))\n",
    "plt.ylabel(\"Accuracy\", fontsize=14)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To improve this result further, you could:\n",
    "* Compare many more models and tune hyperparameters using cross validation and grid search,\n",
    "* Do more feature engineering, for example:\n",
    "  * replace **SibSp** and **Parch** with their sum,\n",
    "  * try to identify parts of names that correlate well with the **Survived** attribute (e.g. if the name contains \"Countess\", then survival seems more likely),\n",
    "* try to convert numerical attributes to categorical attributes: for example, different age groups had very different survival rates (see below), so it may help to create an age bucket category and use it instead of the age. Similarly, it may be useful to have a special category for people traveling alone since only 30% of them survived (see below)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Survived</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>AgeBucket</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0.0</th>\n",
       "      <td>0.576923</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15.0</th>\n",
       "      <td>0.362745</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30.0</th>\n",
       "      <td>0.423256</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45.0</th>\n",
       "      <td>0.404494</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>60.0</th>\n",
       "      <td>0.240000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75.0</th>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           Survived\n",
       "AgeBucket          \n",
       "0.0        0.576923\n",
       "15.0       0.362745\n",
       "30.0       0.423256\n",
       "45.0       0.404494\n",
       "60.0       0.240000\n",
       "75.0       1.000000"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data[\"AgeBucket\"] = train_data[\"Age\"] // 15 * 15\n",
    "train_data[[\"AgeBucket\", \"Survived\"]].groupby(['AgeBucket']).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Survived</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>RelativesOnboard</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.303538</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.552795</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.578431</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.724138</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.200000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.136364</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>0.333333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  Survived\n",
       "RelativesOnboard          \n",
       "0                 0.303538\n",
       "1                 0.552795\n",
       "2                 0.578431\n",
       "3                 0.724138\n",
       "4                 0.200000\n",
       "5                 0.136364\n",
       "6                 0.333333\n",
       "7                 0.000000\n",
       "10                0.000000"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data[\"RelativesOnboard\"] = train_data[\"SibSp\"] + train_data[\"Parch\"]\n",
    "train_data[[\"RelativesOnboard\", \"Survived\"]].groupby(['RelativesOnboard']).mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Spam classifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, let's fetch the data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import tarfile\n",
    "import urllib\n",
    "\n",
    "DOWNLOAD_ROOT = \"http://spamassassin.apache.org/old/publiccorpus/\"\n",
    "HAM_URL = DOWNLOAD_ROOT + \"20030228_easy_ham.tar.bz2\"\n",
    "SPAM_URL = DOWNLOAD_ROOT + \"20030228_spam.tar.bz2\"\n",
    "SPAM_PATH = os.path.join(\"datasets\", \"spam\")\n",
    "\n",
    "def fetch_spam_data(spam_url=SPAM_URL, spam_path=SPAM_PATH):\n",
    "    if not os.path.isdir(spam_path):\n",
    "        os.makedirs(spam_path)\n",
    "    for filename, url in ((\"ham.tar.bz2\", HAM_URL), (\"spam.tar.bz2\", SPAM_URL)):\n",
    "        path = os.path.join(spam_path, filename)\n",
    "        if not os.path.isfile(path):\n",
    "            urllib.request.urlretrieve(url, path)\n",
    "        tar_bz2_file = tarfile.open(path)\n",
    "        tar_bz2_file.extractall(path=SPAM_PATH)\n",
    "        tar_bz2_file.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [],
   "source": [
    "fetch_spam_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, let's load all the emails:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [],
   "source": [
    "HAM_DIR = os.path.join(SPAM_PATH, \"easy_ham\")\n",
    "SPAM_DIR = os.path.join(SPAM_PATH, \"spam\")\n",
    "ham_filenames = [name for name in sorted(os.listdir(HAM_DIR)) if len(name) > 20]\n",
    "spam_filenames = [name for name in sorted(os.listdir(SPAM_DIR)) if len(name) > 20]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2500"
      ]
     },
     "execution_count": 130,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ham_filenames)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "500"
      ]
     },
     "execution_count": 131,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(spam_filenames)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can use Python's `email` module to parse these emails (this handles headers, encoding, and so on):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {},
   "outputs": [],
   "source": [
    "import email\n",
    "import email.policy\n",
    "\n",
    "def load_email(is_spam, filename, spam_path=SPAM_PATH):\n",
    "    directory = \"spam\" if is_spam else \"easy_ham\"\n",
    "    with open(os.path.join(spam_path, directory, filename), \"rb\") as f:\n",
    "        return email.parser.BytesParser(policy=email.policy.default).parse(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {},
   "outputs": [],
   "source": [
    "ham_emails = [load_email(is_spam=False, filename=name) for name in ham_filenames]\n",
    "spam_emails = [load_email(is_spam=True, filename=name) for name in spam_filenames]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's look at one example of ham and one example of spam, to get a feel of what the data looks like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Martin A posted:\n",
      "Tassos Papadopoulos, the Greek sculptor behind the plan, judged that the\n",
      " limestone of Mount Kerdylio, 70 miles east of Salonika and not far from the\n",
      " Mount Athos monastic community, was ideal for the patriotic sculpture. \n",
      " \n",
      " As well as Alexander's granite features, 240 ft high and 170 ft wide, a\n",
      " museum, a restored amphitheatre and car park for admiring crowds are\n",
      "planned\n",
      "---------------------\n",
      "So is this mountain limestone or granite?\n",
      "If it's limestone, it'll weather pretty fast.\n",
      "\n",
      "------------------------ Yahoo! Groups Sponsor ---------------------~-->\n",
      "4 DVDs Free +s&p Join Now\n",
      "http://us.click.yahoo.com/pt6YBB/NXiEAA/mG3HAA/7gSolB/TM\n",
      "---------------------------------------------------------------------~->\n",
      "\n",
      "To unsubscribe from this group, send an email to:\n",
      "forteana-unsubscribe@egroups.com\n",
      "\n",
      " \n",
      "\n",
      "Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/\n"
     ]
    }
   ],
   "source": [
    "print(ham_emails[1].get_content().strip())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help wanted.  We are a 14 year old fortune 500 company, that is\n",
      "growing at a tremendous rate.  We are looking for individuals who\n",
      "want to work from home.\n",
      "\n",
      "This is an opportunity to make an excellent income.  No experience\n",
      "is required.  We will train you.\n",
      "\n",
      "So if you are looking to be employed from home with a career that has\n",
      "vast opportunities, then go:\n",
      "\n",
      "http://www.basetel.com/wealthnow\n",
      "\n",
      "We are looking for energetic and self motivated people.  If that is you\n",
      "than click on the link and fill out the form, and one of our\n",
      "employement specialist will contact you.\n",
      "\n",
      "To be removed from our link simple go to:\n",
      "\n",
      "http://www.basetel.com/remove.html\n",
      "\n",
      "\n",
      "4139vOLW7-758DoDY1425FRhM1-764SMFc8513fCsLl40\n"
     ]
    }
   ],
   "source": [
    "print(spam_emails[6].get_content().strip())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some emails are actually multipart, with images and attachments (which can have their own attachments). Let's look at the various types of structures we have:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_email_structure(email):\n",
    "    if isinstance(email, str):\n",
    "        return email\n",
    "    payload = email.get_payload()\n",
    "    if isinstance(payload, list):\n",
    "        return \"multipart({})\".format(\", \".join([\n",
    "            get_email_structure(sub_email)\n",
    "            for sub_email in payload\n",
    "        ]))\n",
    "    else:\n",
    "        return email.get_content_type()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "\n",
    "def structures_counter(emails):\n",
    "    structures = Counter()\n",
    "    for email in emails:\n",
    "        structure = get_email_structure(email)\n",
    "        structures[structure] += 1\n",
    "    return structures"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('text/plain', 2408),\n",
       " ('multipart(text/plain, application/pgp-signature)', 66),\n",
       " ('multipart(text/plain, text/html)', 8),\n",
       " ('multipart(text/plain, text/plain)', 4),\n",
       " ('multipart(text/plain)', 3),\n",
       " ('multipart(text/plain, application/octet-stream)', 2),\n",
       " ('multipart(text/plain, text/enriched)', 1),\n",
       " ('multipart(text/plain, application/ms-tnef, text/plain)', 1),\n",
       " ('multipart(multipart(text/plain, text/plain, text/plain), application/pgp-signature)',\n",
       "  1),\n",
       " ('multipart(text/plain, video/mng)', 1),\n",
       " ('multipart(text/plain, multipart(text/plain))', 1),\n",
       " ('multipart(text/plain, application/x-pkcs7-signature)', 1),\n",
       " ('multipart(text/plain, multipart(text/plain, text/plain), text/rfc822-headers)',\n",
       "  1),\n",
       " ('multipart(text/plain, multipart(text/plain, text/plain), multipart(multipart(text/plain, application/x-pkcs7-signature)))',\n",
       "  1),\n",
       " ('multipart(text/plain, application/x-java-applet)', 1)]"
      ]
     },
     "execution_count": 138,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "structures_counter(ham_emails).most_common()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('text/plain', 218),\n",
       " ('text/html', 183),\n",
       " ('multipart(text/plain, text/html)', 45),\n",
       " ('multipart(text/html)', 20),\n",
       " ('multipart(text/plain)', 19),\n",
       " ('multipart(multipart(text/html))', 5),\n",
       " ('multipart(text/plain, image/jpeg)', 3),\n",
       " ('multipart(text/html, application/octet-stream)', 2),\n",
       " ('multipart(text/plain, application/octet-stream)', 1),\n",
       " ('multipart(text/html, text/plain)', 1),\n",
       " ('multipart(multipart(text/html), application/octet-stream, image/jpeg)', 1),\n",
       " ('multipart(multipart(text/plain, text/html), image/gif)', 1),\n",
       " ('multipart/alternative', 1)]"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "structures_counter(spam_emails).most_common()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It seems that the ham emails are more often plain text, while spam has quite a lot of HTML. Moreover, quite a few ham emails are signed using PGP, while no spam is. In short, it seems that the email structure is useful information to have."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's take a look at the email headers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Return-Path : <12a1mailbot1@web.de>\n",
      "Delivered-To : zzzz@localhost.spamassassin.taint.org\n",
      "Received : from localhost (localhost [127.0.0.1])\tby phobos.labs.spamassassin.taint.org (Postfix) with ESMTP id 136B943C32\tfor <zzzz@localhost>; Thu, 22 Aug 2002 08:17:21 -0400 (EDT)\n",
      "Received : from mail.webnote.net [193.120.211.219]\tby localhost with POP3 (fetchmail-5.9.0)\tfor zzzz@localhost (single-drop); Thu, 22 Aug 2002 13:17:21 +0100 (IST)\n",
      "Received : from dd_it7 ([210.97.77.167])\tby webnote.net (8.9.3/8.9.3) with ESMTP id NAA04623\tfor <zzzz@spamassassin.taint.org>; Thu, 22 Aug 2002 13:09:41 +0100\n",
      "From : 12a1mailbot1@web.de\n",
      "Received : from r-smtp.korea.com - 203.122.2.197 by dd_it7  with Microsoft SMTPSVC(5.5.1775.675.6);\t Sat, 24 Aug 2002 09:42:10 +0900\n",
      "To : dcek1a1@netsgo.com\n",
      "Subject : Life Insurance - Why Pay More?\n",
      "Date : Wed, 21 Aug 2002 20:31:57 -1600\n",
      "MIME-Version : 1.0\n",
      "Message-ID : <0103c1042001882DD_IT7@dd_it7>\n",
      "Content-Type : text/html; charset=\"iso-8859-1\"\n",
      "Content-Transfer-Encoding : quoted-printable\n"
     ]
    }
   ],
   "source": [
    "for header, value in spam_emails[0].items():\n",
    "    print(header,\":\",value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There's probably a lot of useful information in there, such as the sender's email address (12a1mailbot1@web.de looks fishy), but we will just focus on the `Subject` header:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Life Insurance - Why Pay More?'"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spam_emails[0][\"Subject\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, before we learn too much about the data, let's not forget to split it into a training set and a test set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X = np.array(ham_emails + spam_emails)\n",
    "y = np.array([0] * len(ham_emails) + [1] * len(spam_emails))\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, let's start writing the preprocessing functions. First, we will need a function to convert HTML to plain text. Arguably the best way to do this would be to use the great [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/) library, but I would like to avoid adding another dependency to this project, so let's hack a quick & dirty solution using regular expressions (at the risk of [un̨ho͞ly radiańcé destro҉ying all enli̍̈́̂̈́ghtenment](https://stackoverflow.com/a/1732454/38626)). The following function first drops the `<head>` section, then converts all `<a>` tags to the word HYPERLINK, then it gets rid of all HTML tags, leaving only the plain text. For readability, it also replaces multiple newlines with single newlines, and finally it unescapes html entities (such as `&gt;` or `&nbsp;`):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "from html import unescape\n",
    "\n",
    "def html_to_plain_text(html):\n",
    "    text = re.sub('<head.*?>.*?</head>', '', html, flags=re.M | re.S | re.I)\n",
    "    text = re.sub('<a\\s.*?>', ' HYPERLINK ', text, flags=re.M | re.S | re.I)\n",
    "    text = re.sub('<.*?>', '', text, flags=re.M | re.S)\n",
    "    text = re.sub(r'(\\s*\\n)+', '\\n', text, flags=re.M | re.S)\n",
    "    return unescape(text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see if it works. This is HTML spam:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<HTML><HEAD><TITLE></TITLE><META http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1252\"><STYLE>A:link {TEX-DECORATION: none}A:active {TEXT-DECORATION: none}A:visited {TEXT-DECORATION: none}A:hover {COLOR: #0033ff; TEXT-DECORATION: underline}</STYLE><META content=\"MSHTML 6.00.2713.1100\" name=\"GENERATOR\"></HEAD>\n",
      "<BODY text=\"#000000\" vLink=\"#0033ff\" link=\"#0033ff\" bgColor=\"#CCCC99\"><TABLE borderColor=\"#660000\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\" width=\"100%\"><TR><TD bgColor=\"#CCCC99\" valign=\"top\" colspan=\"2\" height=\"27\">\n",
      "<font size=\"6\" face=\"Arial, Helvetica, sans-serif\" color=\"#660000\">\n",
      "<b>OTC</b></font></TD></TR><TR><TD height=\"2\" bgcolor=\"#6a694f\">\n",
      "<font size=\"5\" face=\"Times New Roman, Times, serif\" color=\"#FFFFFF\">\n",
      "<b>&nbsp;Newsletter</b></font></TD><TD height=\"2\" bgcolor=\"#6a694f\"><div align=\"right\"><font color=\"#FFFFFF\">\n",
      "<b>Discover Tomorrow's Winners&nbsp;</b></font></div></TD></TR><TR><TD height=\"25\" colspan=\"2\" bgcolor=\"#CCCC99\"><table width=\"100%\" border=\"0\"  ...\n"
     ]
    }
   ],
   "source": [
    "html_spam_emails = [email for email in X_train[y_train==1]\n",
    "                    if get_email_structure(email) == \"text/html\"]\n",
    "sample_html_spam = html_spam_emails[7]\n",
    "print(sample_html_spam.get_content().strip()[:1000], \"...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And this is the resulting plain text:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "OTC\n",
      " Newsletter\n",
      "Discover Tomorrow's Winners \n",
      "For Immediate Release\n",
      "Cal-Bay (Stock Symbol: CBYI)\n",
      "Watch for analyst \"Strong Buy Recommendations\" and several advisory newsletters picking CBYI.  CBYI has filed to be traded on the OTCBB, share prices historically INCREASE when companies get listed on this larger trading exchange. CBYI is trading around 25 cents and should skyrocket to $2.66 - $3.25 a share in the near future.\n",
      "Put CBYI on your watch list, acquire a position TODAY.\n",
      "REASONS TO INVEST IN CBYI\n",
      "A profitable company and is on track to beat ALL earnings estimates!\n",
      "One of the FASTEST growing distributors in environmental & safety equipment instruments.\n",
      "Excellent management team, several EXCLUSIVE contracts.  IMPRESSIVE client list including the U.S. Air Force, Anheuser-Busch, Chevron Refining and Mitsubishi Heavy Industries, GE-Energy & Environmental Research.\n",
      "RAPIDLY GROWING INDUSTRY\n",
      "Industry revenues exceed $900 million, estimates indicate that there could be as much as $25 billi ...\n"
     ]
    }
   ],
   "source": [
    "print(html_to_plain_text(sample_html_spam.get_content())[:1000], \"...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great! Now let's write a function that takes an email as input and returns its content as plain text, whatever its format is:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [],
   "source": [
    "def email_to_text(email):\n",
    "    html = None\n",
    "    for part in email.walk():\n",
    "        ctype = part.get_content_type()\n",
    "        if not ctype in (\"text/plain\", \"text/html\"):\n",
    "            continue\n",
    "        try:\n",
    "            content = part.get_content()\n",
    "        except: # in case of encoding issues\n",
    "            content = str(part.get_payload())\n",
    "        if ctype == \"text/plain\":\n",
    "            return content\n",
    "        else:\n",
    "            html = content\n",
    "    if html:\n",
    "        return html_to_plain_text(html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "OTC\n",
      " Newsletter\n",
      "Discover Tomorrow's Winners \n",
      "For Immediate Release\n",
      "Cal-Bay (Stock Symbol: CBYI)\n",
      "Wat ...\n"
     ]
    }
   ],
   "source": [
    "print(email_to_text(sample_html_spam)[:100], \"...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's throw in some stemming! For this to work, you need to install the Natural Language Toolkit ([NLTK](http://www.nltk.org/)). It's as simple as running the following command (don't forget to activate your virtualenv first; if you don't have one, you will likely need administrator rights, or use the `--user` option):\n",
    "\n",
    "`$ pip3 install nltk`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Computations => comput\n",
      "Computation => comput\n",
      "Computing => comput\n",
      "Computed => comput\n",
      "Compute => comput\n",
      "Compulsive => compuls\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    import nltk\n",
    "\n",
    "    stemmer = nltk.PorterStemmer()\n",
    "    for word in (\"Computations\", \"Computation\", \"Computing\", \"Computed\", \"Compute\", \"Compulsive\"):\n",
    "        print(word, \"=>\", stemmer.stem(word))\n",
    "except ImportError:\n",
    "    print(\"Error: stemming requires the NLTK module.\")\n",
    "    stemmer = None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will also need a way to replace URLs with the word \"URL\". For this, we could use hard core [regular expressions](https://mathiasbynens.be/demo/url-regex) but we will just use the [urlextract](https://github.com/lipoja/URLExtract) library. You can install it with the following command (don't forget to activate your virtualenv first; if you don't have one, you will likely need administrator rights, or use the `--user` option):\n",
    "\n",
    "`$ pip3 install urlextract`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [],
   "source": [
    "# if running this notebook on Colab, we just pip install urlextract\n",
    "try:\n",
    "    import google.colab\n",
    "    !pip install -q -U urlextract\n",
    "except ImportError:\n",
    "    pass # not running on Colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['github.com', 'https://youtu.be/7Pq-S557XQU?t=3m32s']\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    import urlextract # may require an Internet connection to download root domain names\n",
    "    \n",
    "    url_extractor = urlextract.URLExtract()\n",
    "    print(url_extractor.find_urls(\"Will it detect github.com and https://youtu.be/7Pq-S557XQU?t=3m32s\"))\n",
    "except ImportError:\n",
    "    print(\"Error: replacing URLs requires the urlextract module.\")\n",
    "    url_extractor = None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are ready to put all this together into a transformer that we will use to convert emails to word counters. Note that we split sentences into words using Python's `split()` method, which uses whitespaces for word boundaries. This works for many written languages, but not all. For example, Chinese and Japanese scripts generally don't use spaces between words, and Vietnamese often uses spaces even between syllables. It's okay in this exercise, because the dataset is (mostly) in English."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.base import BaseEstimator, TransformerMixin\n",
    "\n",
    "class EmailToWordCounterTransformer(BaseEstimator, TransformerMixin):\n",
    "    def __init__(self, strip_headers=True, lower_case=True, remove_punctuation=True,\n",
    "                 replace_urls=True, replace_numbers=True, stemming=True):\n",
    "        self.strip_headers = strip_headers\n",
    "        self.lower_case = lower_case\n",
    "        self.remove_punctuation = remove_punctuation\n",
    "        self.replace_urls = replace_urls\n",
    "        self.replace_numbers = replace_numbers\n",
    "        self.stemming = stemming\n",
    "    def fit(self, X, y=None):\n",
    "        return self\n",
    "    def transform(self, X, y=None):\n",
    "        X_transformed = []\n",
    "        for email in X:\n",
    "            text = email_to_text(email) or \"\"\n",
    "            if self.lower_case:\n",
    "                text = text.lower()\n",
    "            if self.replace_urls and url_extractor is not None:\n",
    "                urls = list(set(url_extractor.find_urls(text)))\n",
    "                urls.sort(key=lambda url: len(url), reverse=True)\n",
    "                for url in urls:\n",
    "                    text = text.replace(url, \" URL \")\n",
    "            if self.replace_numbers:\n",
    "                text = re.sub(r'\\d+(?:\\.\\d*(?:[eE]\\d+))?', 'NUMBER', text)\n",
    "            if self.remove_punctuation:\n",
    "                text = re.sub(r'\\W+', ' ', text, flags=re.M)\n",
    "            word_counts = Counter(text.split())\n",
    "            if self.stemming and stemmer is not None:\n",
    "                stemmed_word_counts = Counter()\n",
    "                for word, count in word_counts.items():\n",
    "                    stemmed_word = stemmer.stem(word)\n",
    "                    stemmed_word_counts[stemmed_word] += count\n",
    "                word_counts = stemmed_word_counts\n",
    "            X_transformed.append(word_counts)\n",
    "        return np.array(X_transformed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try this transformer on a few emails:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([Counter({'chuck': 1, 'murcko': 1, 'wrote': 1, 'stuff': 1, 'yawn': 1, 'r': 1}),\n",
       "       Counter({'the': 11, 'of': 9, 'and': 8, 'all': 3, 'christian': 3, 'to': 3, 'by': 3, 'jefferson': 2, 'i': 2, 'have': 2, 'superstit': 2, 'one': 2, 'on': 2, 'been': 2, 'ha': 2, 'half': 2, 'rogueri': 2, 'teach': 2, 'jesu': 2, 'some': 1, 'interest': 1, 'quot': 1, 'url': 1, 'thoma': 1, 'examin': 1, 'known': 1, 'word': 1, 'do': 1, 'not': 1, 'find': 1, 'in': 1, 'our': 1, 'particular': 1, 'redeem': 1, 'featur': 1, 'they': 1, 'are': 1, 'alik': 1, 'found': 1, 'fabl': 1, 'mytholog': 1, 'million': 1, 'innoc': 1, 'men': 1, 'women': 1, 'children': 1, 'sinc': 1, 'introduct': 1, 'burnt': 1, 'tortur': 1, 'fine': 1, 'imprison': 1, 'what': 1, 'effect': 1, 'thi': 1, 'coercion': 1, 'make': 1, 'world': 1, 'fool': 1, 'other': 1, 'hypocrit': 1, 'support': 1, 'error': 1, 'over': 1, 'earth': 1, 'six': 1, 'histor': 1, 'american': 1, 'john': 1, 'e': 1, 'remsburg': 1, 'letter': 1, 'william': 1, 'short': 1, 'again': 1, 'becom': 1, 'most': 1, 'pervert': 1, 'system': 1, 'that': 1, 'ever': 1, 'shone': 1, 'man': 1, 'absurd': 1, 'untruth': 1, 'were': 1, 'perpetr': 1, 'upon': 1, 'a': 1, 'larg': 1, 'band': 1, 'dupe': 1, 'import': 1, 'led': 1, 'paul': 1, 'first': 1, 'great': 1, 'corrupt': 1}),\n",
       "       Counter({'url': 5, 's': 3, 'group': 3, 'to': 3, 'in': 2, 'forteana': 2, 'martin': 2, 'an': 2, 'and': 2, 'we': 2, 'is': 2, 'yahoo': 2, 'unsubscrib': 2, 'y': 1, 'adamson': 1, 'wrote': 1, 'for': 1, 'altern': 1, 'rather': 1, 'more': 1, 'factual': 1, 'base': 1, 'rundown': 1, 'on': 1, 'hamza': 1, 'career': 1, 'includ': 1, 'hi': 1, 'belief': 1, 'that': 1, 'all': 1, 'non': 1, 'muslim': 1, 'yemen': 1, 'should': 1, 'be': 1, 'murder': 1, 'outright': 1, 'know': 1, 'how': 1, 'unbias': 1, 'memri': 1, 'don': 1, 't': 1, 'html': 1, 'rob': 1, 'sponsor': 1, 'number': 1, 'dvd': 1, 'free': 1, 'p': 1, 'join': 1, 'now': 1, 'from': 1, 'thi': 1, 'send': 1, 'email': 1, 'your': 1, 'use': 1, 'of': 1, 'subject': 1})],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_few = X_train[:3]\n",
    "X_few_wordcounts = EmailToWordCounterTransformer().fit_transform(X_few)\n",
    "X_few_wordcounts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This looks about right!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we have the word counts, and we need to convert them to vectors. For this, we will build another transformer whose `fit()` method will build the vocabulary (an ordered list of the most common words) and whose `transform()` method will use the vocabulary to convert word counts to vectors. The output is a sparse matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.sparse import csr_matrix\n",
    "\n",
    "class WordCounterToVectorTransformer(BaseEstimator, TransformerMixin):\n",
    "    def __init__(self, vocabulary_size=1000):\n",
    "        self.vocabulary_size = vocabulary_size\n",
    "    def fit(self, X, y=None):\n",
    "        total_count = Counter()\n",
    "        for word_count in X:\n",
    "            for word, count in word_count.items():\n",
    "                total_count[word] += min(count, 10)\n",
    "        most_common = total_count.most_common()[:self.vocabulary_size]\n",
    "        self.most_common_ = most_common\n",
    "        self.vocabulary_ = {word: index + 1 for index, (word, count) in enumerate(most_common)}\n",
    "        return self\n",
    "    def transform(self, X, y=None):\n",
    "        rows = []\n",
    "        cols = []\n",
    "        data = []\n",
    "        for row, word_count in enumerate(X):\n",
    "            for word, count in word_count.items():\n",
    "                rows.append(row)\n",
    "                cols.append(self.vocabulary_.get(word, 0))\n",
    "                data.append(count)\n",
    "        return csr_matrix((data, (rows, cols)), shape=(len(X), self.vocabulary_size + 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<3x11 sparse matrix of type '<class 'numpy.int64'>'\n",
       "\twith 20 stored elements in Compressed Sparse Row format>"
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vocab_transformer = WordCounterToVectorTransformer(vocabulary_size=10)\n",
    "X_few_vectors = vocab_transformer.fit_transform(X_few_wordcounts)\n",
    "X_few_vectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],\n",
       "       [99, 11,  9,  8,  1,  3,  3,  1,  3,  2,  3],\n",
       "       [65,  0,  1,  2,  5,  3,  1,  2,  0,  1,  0]], dtype=int64)"
      ]
     },
     "execution_count": 155,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_few_vectors.toarray()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What does this matrix mean? Well, the 99 in the second row, first column, means that the second email contains 99 words that are not part of the vocabulary. The 11 next to it means that the first word in the vocabulary is present 11 times in this email. The 9 next to it means that the second word is present 9 times, and so on. You can look at the vocabulary to know which words we are talking about. The first word is \"the\", the second word is \"of\", etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'the': 1,\n",
       " 'of': 2,\n",
       " 'and': 3,\n",
       " 'url': 4,\n",
       " 'to': 5,\n",
       " 'all': 6,\n",
       " 'in': 7,\n",
       " 'christian': 8,\n",
       " 'on': 9,\n",
       " 'by': 10}"
      ]
     },
     "execution_count": 156,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vocab_transformer.vocabulary_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are now ready to train our first spam classifier! Let's transform the whole dataset:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.pipeline import Pipeline\n",
    "\n",
    "preprocess_pipeline = Pipeline([\n",
    "    (\"email_to_wordcount\", EmailToWordCounterTransformer()),\n",
    "    (\"wordcount_to_vector\", WordCounterToVectorTransformer()),\n",
    "])\n",
    "\n",
    "X_train_transformed = preprocess_pipeline.fit_transform(X_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**: to be future-proof, we set `solver=\"lbfgs\"` since this will be the default value in Scikit-Learn 0.22."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "/Users/ageron/.virtualenvs/tf2/lib/python3.6/site-packages/sklearn/linear_model/logistic.py:758: ConvergenceWarning: lbfgs failed to converge. Increase the number of iterations.\n",
      "  \"of iterations.\", ConvergenceWarning)\n",
      "[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.1s remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  ................................................................\n",
      "[CV] .................................... , score=0.985, total=   0.1s\n",
      "[CV]  ................................................................\n",
      "[CV] .................................... , score=0.985, total=   0.1s\n",
      "[CV]  ................................................................\n",
      "[CV] ................................... , score=0.9925, total=   0.1s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/ageron/.virtualenvs/tf2/lib/python3.6/site-packages/sklearn/linear_model/logistic.py:758: ConvergenceWarning: lbfgs failed to converge. Increase the number of iterations.\n",
      "  \"of iterations.\", ConvergenceWarning)\n",
      "[Parallel(n_jobs=1)]: Done   2 out of   2 | elapsed:    0.2s remaining:    0.0s\n",
      "/Users/ageron/.virtualenvs/tf2/lib/python3.6/site-packages/sklearn/linear_model/logistic.py:758: ConvergenceWarning: lbfgs failed to converge. Increase the number of iterations.\n",
      "  \"of iterations.\", ConvergenceWarning)\n",
      "[Parallel(n_jobs=1)]: Done   3 out of   3 | elapsed:    0.4s finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.9874999999999999"
      ]
     },
     "execution_count": 158,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "log_clf = LogisticRegression(solver=\"lbfgs\", random_state=42)\n",
    "score = cross_val_score(log_clf, X_train_transformed, y_train, cv=3, verbose=3)\n",
    "score.mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Over 98.7%, not bad for a first try! :) However, remember that we are using the \"easy\" dataset. You can try with the harder datasets, the results won't be so amazing. You would have to try multiple models, select the best ones and fine-tune them using cross-validation, and so on.\n",
    "\n",
    "But you get the picture, so let's stop now, and just print out the precision/recall we get on the test set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Precision: 95.88%\n",
      "Recall: 97.89%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/ageron/.virtualenvs/tf2/lib/python3.6/site-packages/sklearn/linear_model/logistic.py:758: ConvergenceWarning: lbfgs failed to converge. Increase the number of iterations.\n",
      "  \"of iterations.\", ConvergenceWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score, recall_score\n",
    "\n",
    "X_test_transformed = preprocess_pipeline.transform(X_test)\n",
    "\n",
    "log_clf = LogisticRegression(solver=\"lbfgs\", random_state=42)\n",
    "log_clf.fit(X_train_transformed, y_train)\n",
    "\n",
    "y_pred = log_clf.predict(X_test_transformed)\n",
    "\n",
    "print(\"Precision: {:.2f}%\".format(100 * precision_score(y_test, y_pred)))\n",
    "print(\"Recall: {:.2f}%\".format(100 * recall_score(y_test, y_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "nav_menu": {},
  "toc": {
   "navigate_menu": true,
   "number_sections": true,
   "sideBar": true,
   "threshold": 6,
   "toc_cell": false,
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
